From 7a3bd8652209cd7214ee260250c2a5d32b2ee286 Mon Sep 17 00:00:00 2001 From: str4d Date: Thu, 2 Jun 2016 04:06:56 +0000 Subject: [PATCH] Use ConversationManager for timestamps and unread counts --- .../android/contact/ContactListFragment.java | 104 ++++---------- .../android/contact/ContactListItem.java | 40 +++--- .../android/contact/ConversationActivity.java | 8 +- .../forum/ForumSharingStatusActivity.java | 4 +- .../forum/SelectableContactListItem.java | 3 +- .../introduction/ContactChooserFragment.java | 27 +--- .../api/clients/ReadableMessageConstants.java | 10 ++ .../api/clients/ReadableMessageManager.java | 26 ++++ .../api/conversation/ConversationManager.java | 18 ++- .../api/forum/ForumSharingManager.java | 3 - .../introduction/IntroductionConstants.java | 1 - .../api/introduction/IntroductionManager.java | 6 +- .../api/messaging/MessagingManager.java | 6 +- .../api/sharing/SharingConstants.java | 3 - .../api/sharing/SharingManager.java | 14 +- .../clients/ReadableMessageManagerImpl.java | 127 ++++++++++++++++++ .../conversation/ConversationManagerImpl.java | 53 +++++--- .../introduction/IntroduceeEngine.java | 5 +- .../introduction/IntroducerEngine.java | 7 +- .../introduction/IntroductionManagerImpl.java | 89 ++++++------ .../introduction/IntroductionValidator.java | 10 +- .../introduction/MessageSender.java | 4 +- .../messaging/MessagingManagerImpl.java | 49 +++---- .../messaging/PrivateMessageValidator.java | 9 +- .../sharing/BlogSharingValidator.java | 8 +- .../sharing/ForumSharingValidator.java | 8 +- .../sharing/SharingManagerImpl.java | 43 +++--- .../introduction/IntroduceeManagerTest.java | 9 +- .../introduction/IntroducerManagerTest.java | 6 +- .../IntroductionManagerImplTest.java | 4 +- 30 files changed, 411 insertions(+), 293 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/clients/ReadableMessageConstants.java create mode 100644 briar-api/src/org/briarproject/api/clients/ReadableMessageManager.java create mode 100644 briar-core/src/org/briarproject/clients/ReadableMessageManagerImpl.java diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index b27b4d0ff..820fc9ccb 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -23,11 +23,7 @@ import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.conversation.ConversationForumInvitationItem; -import org.briarproject.api.conversation.ConversationIntroductionRequestItem; -import org.briarproject.api.conversation.ConversationIntroductionResponseItem; -import org.briarproject.api.conversation.ConversationItem; -import org.briarproject.api.conversation.ConversationMessageItem; +import org.briarproject.api.conversation.ConversationManager; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchContactException; import org.briarproject.api.event.ContactAddedEvent; @@ -40,22 +36,14 @@ import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; import org.briarproject.api.event.MessageStateChangedEvent; import org.briarproject.api.event.PrivateMessageReceivedEvent; -import org.briarproject.api.forum.ForumInvitationMessage; -import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.api.introduction.IntroductionManager; -import org.briarproject.api.introduction.IntroductionMessage; -import org.briarproject.api.introduction.IntroductionRequest; -import org.briarproject.api.introduction.IntroductionResponse; -import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.GroupId; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.logging.Logger; @@ -88,11 +76,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Inject protected volatile IdentityManager identityManager; @Inject - protected volatile MessagingManager messagingManager; - @Inject - protected volatile IntroductionManager introductionManager; - @Inject - protected volatile ForumSharingManager forumSharingManager; + protected volatile ConversationManager conversationManager; public static ContactListFragment newInstance() { @@ -208,15 +192,19 @@ public class ContactListFragment extends BaseFragment implements EventListener { try { ContactId id = c.getId(); GroupId groupId = - messagingManager.getConversationId(id); - Collection messages = - getMessages(id); + conversationManager.getConversationId(id); boolean connected = connectionRegistry.isConnected(c.getId()); LocalAuthor localAuthor = identityManager .getLocalAuthor(c.getLocalAuthorId()); + long timestamp = conversationManager.getTimestamp(id); + long now1 = System.currentTimeMillis(); + int unread = conversationManager.getUnreadCount(id); + long duration = System.currentTimeMillis() - now1; + if (LOG.isLoggable(INFO)) + LOG.info("Loading unread messages took " + duration + " ms"); contacts.add(new ContactListItem(c, localAuthor, - connected, groupId, messages)); + connected, groupId, timestamp, unread)); } catch (NoSuchContactException e) { // Continue } @@ -264,13 +252,11 @@ public class ContactListFragment extends BaseFragment implements EventListener { LOG.info("Message received, update contact"); PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; PrivateMessageHeader h = p.getMessageHeader(); - updateItem(p.getGroupId(), ConversationMessageItem.from(h)); + updateItem(p.getGroupId(), h.getTimestamp(), h.isRead()); } else if (e instanceof MessageStateChangedEvent) { MessageStateChangedEvent m = (MessageStateChangedEvent) e; ClientId c = m.getClientId(); - if (m.getState() == DELIVERED && - (c.equals(introductionManager.getClientId()) || - c.equals(forumSharingManager.getClientId()))) { + if (m.getState() == DELIVERED && conversationManager.isWrappedClient(c)) { LOG.info("Message added, reloading"); reloadConversation(m.getMessage().getGroupId()); } @@ -282,10 +268,10 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { try { - ContactId c = messagingManager.getContactId(g); - Collection messages = - getMessages(c); - updateItem(c, messages); + ContactId c = conversationManager.getContactId(g); + long timestamp = conversationManager.getTimestamp(c); + int unread = conversationManager.getUnreadCount(c); + updateItem(c, timestamp, unread); } catch (NoSuchContactException e) { LOG.info("Contact removed"); } catch (DbException e) { @@ -296,29 +282,31 @@ public class ContactListFragment extends BaseFragment implements EventListener { }); } - private void updateItem(final ContactId c, - final Collection messages) { + private void updateItem(final ContactId c, final long timestamp, final int unread) { listener.runOnUiThread(new Runnable() { @Override public void run() { int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItem(position); if (item != null) { - item.setMessages(messages); + item.setTimestamp(timestamp); + item.setUnreadCount(unread); adapter.updateItem(position, item); } } }); } - private void updateItem(final GroupId g, final ConversationItem m) { + private void updateItem(final GroupId g, final long timestamp, final boolean unread) { listener.runOnUiThread(new Runnable() { @Override public void run() { int position = adapter.findItemPosition(g); ContactListItem item = adapter.getItem(position); if (item != null) { - item.addMessage(m); + item.setTimestamp(timestamp); + if (unread) + item.setUnreadCount(item.getUnreadCount() + 1); adapter.updateItem(position, item); } } @@ -349,50 +337,4 @@ public class ContactListFragment extends BaseFragment implements EventListener { } }); } - - // This needs to be called from the DB thread - private Collection getMessages(ContactId id) - throws DbException { - - long now = System.currentTimeMillis(); - - Collection messages = new ArrayList<>(); - - Collection headers = - messagingManager.getMessageHeaders(id); - for (PrivateMessageHeader h : headers) { - messages.add(ConversationMessageItem.from(h)); - } - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading message headers took " + duration + " ms"); - - now = System.currentTimeMillis(); - Collection introductions = - introductionManager - .getIntroductionMessages(id); - for (IntroductionMessage m : introductions) { - if (m instanceof IntroductionRequest) - messages.add(ConversationIntroductionRequestItem - .from((IntroductionRequest) m)); - else - messages.add(ConversationIntroductionResponseItem - .from((IntroductionResponse) m)); - } - duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading introduction messages took " + duration + " ms"); - - now = System.currentTimeMillis(); - Collection invitations = - forumSharingManager.getInvitationMessages(id); - for (ForumInvitationMessage i : invitations) { - messages.add(ConversationForumInvitationItem.from(i)); - } - duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading forum invitations took " + duration + " ms"); - - return messages; - } } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListItem.java b/briar-android/src/org/briarproject/android/contact/ContactListItem.java index b880bc889..c675d6c46 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListItem.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListItem.java @@ -2,6 +2,8 @@ package org.briarproject.android.contact; import org.briarproject.api.contact.Contact; import org.briarproject.api.conversation.ConversationItem; +import org.briarproject.api.conversation.ConversationManager; +import org.briarproject.api.db.DbException; import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.sync.GroupId; @@ -13,40 +15,20 @@ public class ContactListItem { private final Contact contact; private final LocalAuthor localAuthor; private final GroupId groupId; - private boolean connected, empty; + private boolean connected; private long timestamp; private int unread; public ContactListItem(Contact contact, LocalAuthor localAuthor, boolean connected, GroupId groupId, - Collection messages) { + long timestamp, int unread) { this.contact = contact; this.localAuthor = localAuthor; this.groupId = groupId; this.connected = connected; - setMessages(messages); - } - - void setMessages(Collection messages) { - empty = messages == null || messages.isEmpty(); - timestamp = 0; - unread = 0; - if (!empty) { - for (ConversationItem i : messages) { - addMessage(i); - } - } - } - - void addMessage(ConversationItem message) { - empty = empty && message == null; - if (message != null) { - if (message.getTime() > timestamp) timestamp = message.getTime(); - if (message instanceof ConversationItem.IncomingItem && - !((ConversationItem.IncomingItem) message).isRead()) - unread++; - } + this.timestamp = timestamp; + this.unread = unread; } public Contact getContact() { @@ -70,14 +52,22 @@ public class ContactListItem { } boolean isEmpty() { - return empty; + return timestamp < 0; } long getTimestamp() { return timestamp; } + void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + int getUnreadCount() { return unread; } + + void setUnreadCount(int unread) { + this.unread = unread; + } } \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index a34ac9d42..67602b15d 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -38,7 +38,6 @@ import org.briarproject.api.conversation.ConversationIntroductionResponseItem; import org.briarproject.api.conversation.ConversationItem; import org.briarproject.api.conversation.ConversationItem.IncomingItem; import org.briarproject.api.conversation.ConversationManager; -import org.briarproject.api.conversation.ConversationMessageItem; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchContactException; @@ -58,7 +57,6 @@ import org.briarproject.api.introduction.IntroductionRequest; import org.briarproject.api.introduction.IntroductionResponse; import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessageFactory; -import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; @@ -366,7 +364,7 @@ public class ConversationActivity extends BriarActivity SparseArray list = adapter.getIncomingMessages(); for (int i = 0; i < list.size(); i++) { IncomingItem item = list.valueAt(i); - if (!item.isRead()) unread.add((ConversationItem) item); + if (!item.isRead()) unread.add(item); } if (unread.isEmpty()) return; if (LOG.isLoggable(INFO)) @@ -381,7 +379,7 @@ public class ConversationActivity extends BriarActivity try { long now = System.currentTimeMillis(); for (ConversationItem item : unread) - conversationManager.setReadFlag(item, true); + conversationManager.setReadFlag(contactId, item, true); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Marking read took " + duration + " ms"); @@ -488,7 +486,7 @@ public class ConversationActivity extends BriarActivity @Override public void run() { try { - conversationManager.setReadFlag(item, true); + conversationManager.setReadFlag(contactId, item, true); loadMessages(); } catch (DbException e) { if (LOG.isLoggable(WARNING)) diff --git a/briar-android/src/org/briarproject/android/forum/ForumSharingStatusActivity.java b/briar-android/src/org/briarproject/android/forum/ForumSharingStatusActivity.java index 5da3d212c..94c028b00 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumSharingStatusActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumSharingStatusActivity.java @@ -103,7 +103,7 @@ public class ForumSharingStatusActivity extends BriarActivity { .getLocalAuthor(c.getLocalAuthorId()); ContactListItem item = new ContactListItem(c, localAuthor, false, null, - null); + -1, 0); contactItems.add(item); } } catch (DbException e) { @@ -141,7 +141,7 @@ public class ForumSharingStatusActivity extends BriarActivity { .getLocalAuthor(c.getLocalAuthorId()); ContactListItem item = new ContactListItem(c, localAuthor, false, null, - null); + -1, 0); contactItems.add(item); } } catch (DbException e) { diff --git a/briar-android/src/org/briarproject/android/forum/SelectableContactListItem.java b/briar-android/src/org/briarproject/android/forum/SelectableContactListItem.java index ece15fed7..59250fee8 100644 --- a/briar-android/src/org/briarproject/android/forum/SelectableContactListItem.java +++ b/briar-android/src/org/briarproject/android/forum/SelectableContactListItem.java @@ -16,8 +16,7 @@ public class SelectableContactListItem extends ContactListItem { public SelectableContactListItem(Contact contact, LocalAuthor localAuthor, GroupId groupId, boolean selected, boolean disabled) { - super(contact, localAuthor, false, groupId, - Collections.emptyList()); + super(contact, localAuthor, false, groupId, -1, 0); this.selected = selected; this.disabled = disabled; diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java index eadc37223..147ce61cf 100644 --- a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java +++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java @@ -162,14 +162,18 @@ public class ContactChooserFragment extends BaseFragment { ContactId id = c.getId(); GroupId groupId = conversationManager.getConversationId(id); - Collection messages = - getMessages(id); boolean connected = connectionRegistry.isConnected(c.getId()); LocalAuthor localAuthor = identityManager .getLocalAuthor(c.getLocalAuthorId()); + long timestamp = conversationManager.getTimestamp(id); + long now1 = System.currentTimeMillis(); + int unread = conversationManager.getUnreadCount(id); + long duration = System.currentTimeMillis() - now1; + if (LOG.isLoggable(INFO)) + LOG.info("Loading unread messages took " + duration + " ms"); contacts.add(new ContactListItem(c, localAuthor, - connected, groupId, messages)); + connected, groupId, timestamp, unread)); } } displayContacts(localAuthorId, contacts); @@ -213,21 +217,4 @@ public class ContactChooserFragment extends BaseFragment { builder.setNegativeButton(android.R.string.cancel, null); builder.show(); } - - /** - * This needs to be called from the DbThread - */ - private Collection getMessages(ContactId id) - throws DbException { - - long now = System.currentTimeMillis(); - - Collection messages = - conversationManager.getMessages(id, false); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading message headers took " + duration + " ms"); - - return messages; - } } diff --git a/briar-api/src/org/briarproject/api/clients/ReadableMessageConstants.java b/briar-api/src/org/briarproject/api/clients/ReadableMessageConstants.java new file mode 100644 index 000000000..f9ffcf734 --- /dev/null +++ b/briar-api/src/org/briarproject/api/clients/ReadableMessageConstants.java @@ -0,0 +1,10 @@ +package org.briarproject.api.clients; + +public interface ReadableMessageConstants { + + /* Readable Message Local State Metadata */ + String LOCAL = "local"; + String READ = "read"; + String TIMESTAMP = "timestamp"; + String UNREAD = "unread"; +} diff --git a/briar-api/src/org/briarproject/api/clients/ReadableMessageManager.java b/briar-api/src/org/briarproject/api/clients/ReadableMessageManager.java new file mode 100644 index 000000000..591b0fce6 --- /dev/null +++ b/briar-api/src/org/briarproject/api/clients/ReadableMessageManager.java @@ -0,0 +1,26 @@ +package org.briarproject.api.clients; + +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.sync.MessageId; + +public interface ReadableMessageManager { + + /** + * Returns the timestamp of the latest message in the group with the given + * contact, or -1 if the group is empty. + */ + long getTimestamp(ContactId c) throws DbException; + + /** + * Returns the number of unread messages in the group with the given + * contact. + */ + int getUnreadCount(ContactId c) throws DbException; + + /** + * Marks a message as read or unread. + */ + void setReadFlag(ContactId c, MessageId m, boolean local, boolean read) + throws DbException; +} diff --git a/briar-api/src/org/briarproject/api/conversation/ConversationManager.java b/briar-api/src/org/briarproject/api/conversation/ConversationManager.java index d6119c6de..77242b678 100644 --- a/briar-api/src/org/briarproject/api/conversation/ConversationManager.java +++ b/briar-api/src/org/briarproject/api/conversation/ConversationManager.java @@ -17,6 +17,11 @@ public interface ConversationManager { */ ClientId getClientId(); + /** + * Returns true if this is the id of a wrapped client. + */ + boolean isWrappedClient(ClientId clientId); + /** * Stores a local private message, and returns the corresponding item. */ @@ -38,10 +43,15 @@ public interface ConversationManager { List getMessages(ContactId c) throws DbException; /** - * Returns all messages in the given private conversation. + * Returns the timestamp of the latest message in the given private + * conversation, or -1 if the conversation is empty. */ - List getMessages(ContactId c, boolean content) - throws DbException; + long getTimestamp(ContactId c) throws DbException; + + /** + * Returns the number of unread messages in the given private conversation. + */ + int getUnreadCount(ContactId c) throws DbException; /** * Starts a background task to load the content of the given message. @@ -57,5 +67,5 @@ public interface ConversationManager { /** * Marks a conversation item as read or unread. */ - void setReadFlag(ConversationItem item, boolean read) throws DbException; + void setReadFlag(ContactId c, ConversationItem item, boolean read) throws DbException; } diff --git a/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java b/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java index b4ed94152..7b842b574 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java +++ b/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java @@ -47,7 +47,4 @@ public interface ForumSharingManager extends SharingManager getIntroductionMessages(ContactId contactId) throws DbException; - /** Marks an introduction message as read or unread. */ - void setReadFlag(MessageId m, boolean read) throws DbException; - } diff --git a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java index f22a5131a..a8d80c695 100644 --- a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java +++ b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java @@ -1,5 +1,6 @@ package org.briarproject.api.messaging; +import org.briarproject.api.clients.ReadableMessageManager; import org.briarproject.api.contact.ContactId; import org.briarproject.api.db.DbException; import org.briarproject.api.sync.ClientId; @@ -8,7 +9,7 @@ import org.briarproject.api.sync.MessageId; import java.util.Collection; -public interface MessagingManager { +public interface MessagingManager extends ReadableMessageManager { /** Returns the unique ID of the messaging client. */ ClientId getClientId(); @@ -30,7 +31,4 @@ public interface MessagingManager { /** Returns the body of the private message with the given ID. */ byte[] getMessageBody(MessageId m) throws DbException; - - /** Marks a private message as read or unread. */ - void setReadFlag(MessageId m, boolean read) throws DbException; } diff --git a/briar-api/src/org/briarproject/api/sharing/SharingConstants.java b/briar-api/src/org/briarproject/api/sharing/SharingConstants.java index 43d689729..c7a18c49f 100644 --- a/briar-api/src/org/briarproject/api/sharing/SharingConstants.java +++ b/briar-api/src/org/briarproject/api/sharing/SharingConstants.java @@ -14,9 +14,6 @@ public interface SharingConstants { String SESSION_ID = "sessionId"; String STORAGE_ID = "storageId"; String STATE = "state"; - String LOCAL = "local"; - String TIME = "time"; - String READ = "read"; String IS_SHARER = "isSharer"; String SHAREABLE_ID = "shareableId"; String INVITATION_MSG = "invitationMsg"; diff --git a/briar-api/src/org/briarproject/api/sharing/SharingManager.java b/briar-api/src/org/briarproject/api/sharing/SharingManager.java index a2987ef80..230a980bd 100644 --- a/briar-api/src/org/briarproject/api/sharing/SharingManager.java +++ b/briar-api/src/org/briarproject/api/sharing/SharingManager.java @@ -46,7 +46,19 @@ public interface SharingManager groupTimestamp) { + d.put(TIMESTAMP, timestamp); + } + if (!local && (wasRead != read)) { + d.put(UNREAD, read ? (unread > 0 ? unread - 1 : 0) : unread + 1); + } + clientHelper.mergeGroupMetadata(txn, groupId, d); + } +} diff --git a/briar-core/src/org/briarproject/conversation/ConversationManagerImpl.java b/briar-core/src/org/briarproject/conversation/ConversationManagerImpl.java index 1912c40f8..d99006d84 100644 --- a/briar-core/src/org/briarproject/conversation/ConversationManagerImpl.java +++ b/briar-core/src/org/briarproject/conversation/ConversationManagerImpl.java @@ -7,6 +7,7 @@ import org.briarproject.api.conversation.ConversationForumInvitationItem; import org.briarproject.api.conversation.ConversationIntroductionRequestItem; import org.briarproject.api.conversation.ConversationIntroductionResponseItem; import org.briarproject.api.conversation.ConversationItem; +import org.briarproject.api.conversation.ConversationItem.OutgoingItem; import org.briarproject.api.conversation.ConversationItem.Partial; import org.briarproject.api.conversation.ConversationManager; import org.briarproject.api.conversation.ConversationMessageItem; @@ -73,6 +74,12 @@ public class ConversationManagerImpl implements ConversationManager { return CLIENT_ID; } + @Override + public boolean isWrappedClient(ClientId clientId) { + return clientId.equals(introductionManager.getClientId()) || + clientId.equals(forumSharingManager.getClientId()); + } + @Override public ConversationItem addLocalMessage(PrivateMessage m, byte[] body) throws DbException { @@ -101,12 +108,6 @@ public class ConversationManagerImpl implements ConversationManager { @Override public List getMessages(ContactId c) throws DbException { - return getMessages(c, true); - } - - @Override - public List getMessages(ContactId c, boolean content) - throws DbException { Collection headers = messagingManager.getMessageHeaders(c); Collection introductions = @@ -116,11 +117,9 @@ public class ConversationManagerImpl implements ConversationManager { List items = new ArrayList(); for (PrivateMessageHeader h : headers) { ConversationItem item = ConversationMessageItemImpl.from(h); - if (content) { - byte[] body = bodyCache.get(h.getId()); - if (body == null) loadMessageContent((Partial) item); - else ((Partial) item).setContent(body); - } + byte[] body = bodyCache.get(h.getId()); + if (body == null) loadMessageContent((Partial) item); + else ((Partial) item).setContent(body); items.add(item); } for (IntroductionMessage m : introductions) { @@ -141,6 +140,27 @@ public class ConversationManagerImpl implements ConversationManager { return items; } + @Override + public long getTimestamp(ContactId c) throws DbException { + long timestamp = -1; + long t = messagingManager.getTimestamp(c); + if (t > timestamp) timestamp = t; + t = introductionManager.getTimestamp(c); + if (t > timestamp) timestamp = t; + t = forumSharingManager.getTimestamp(c); + if (t > timestamp) timestamp = t; + return timestamp; + } + + @Override + public int getUnreadCount(ContactId c) throws DbException { + int unread = 0; + unread += messagingManager.getUnreadCount(c); + unread += introductionManager.getUnreadCount(c); + unread += forumSharingManager.getUnreadCount(c); + return unread; + } + @Override public void loadMessageContent(final Partial m) { dbExecutor.execute(new Runnable() { @@ -185,16 +205,17 @@ public class ConversationManagerImpl implements ConversationManager { } @Override - public void setReadFlag(ConversationItem item, boolean read) + public void setReadFlag(ContactId c, ConversationItem item, boolean read) throws DbException { MessageId id = item.getId(); + boolean local = item instanceof OutgoingItem; if (item instanceof ConversationMessageItem) { - messagingManager.setReadFlag(id, read); + messagingManager.setReadFlag(c, id, local, read); } else if (item instanceof ConversationIntroductionRequestItem || - item instanceof ConversationIntroductionResponseItem) { - introductionManager.setReadFlag(id, read); + item instanceof ConversationIntroductionResponseItem) { + introductionManager.setReadFlag(c, id, local, read); } else if (item instanceof ConversationForumInvitationItem) { - forumSharingManager.setReadFlag(id, read); + forumSharingManager.setReadFlag(c, id, local, read); } } } diff --git a/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java b/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java index 50af8e754..d6a5bac4e 100644 --- a/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java +++ b/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java @@ -22,6 +22,7 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.introduction.IntroduceeAction.LOCAL_ABORT; import static org.briarproject.api.introduction.IntroduceeAction.LOCAL_ACCEPT; import static org.briarproject.api.introduction.IntroduceeAction.LOCAL_DECLINE; @@ -112,7 +113,7 @@ public class IntroduceeEngine msg.put(E_PUBLIC_KEY, localState.getRaw(OUR_PUBLIC_KEY)); msg.put(TRANSPORT, localAction.getDictionary(TRANSPORT)); } - msg.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); + msg.put(TIMESTAMP, localAction.getLong(MESSAGE_TIME)); messages.add(msg); logAction(currentState, localState, msg); @@ -330,7 +331,7 @@ public class IntroduceeEngine SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID)); MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID)); - long time = msg.getLong(MESSAGE_TIME); + long time = msg.getLong(TIMESTAMP); String name = msg.getString(NAME); String message = msg.getOptionalString(MSG); boolean exists = localState.getBoolean(EXISTS); diff --git a/briar-core/src/org/briarproject/introduction/IntroducerEngine.java b/briar-core/src/org/briarproject/introduction/IntroducerEngine.java index a431fd7e4..116b18447 100644 --- a/briar-core/src/org/briarproject/introduction/IntroducerEngine.java +++ b/briar-core/src/org/briarproject/introduction/IntroducerEngine.java @@ -22,6 +22,7 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.introduction.IntroducerAction.LOCAL_ABORT; import static org.briarproject.api.introduction.IntroducerAction.LOCAL_REQUEST; import static org.briarproject.api.introduction.IntroducerAction.REMOTE_ACCEPT_1; @@ -106,7 +107,7 @@ public class IntroducerEngine if (localAction.containsKey(MSG)) { msg1.put(MSG, localAction.getString(MSG)); } - msg1.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); + msg1.put(TIMESTAMP, localAction.getLong(MESSAGE_TIME)); messages.add(msg1); logLocalAction(currentState, localState, msg1); BdfDictionary msg2 = new BdfDictionary(); @@ -118,7 +119,7 @@ public class IntroducerEngine if (localAction.containsKey(MSG)) { msg2.put(MSG, localAction.getString(MSG)); } - msg2.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); + msg2.put(TIMESTAMP, localAction.getLong(MESSAGE_TIME)); messages.add(msg2); logLocalAction(currentState, localState, msg2); @@ -298,7 +299,7 @@ public class IntroducerEngine SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID)); MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID)); - long time = msg.getLong(MESSAGE_TIME); + long time = msg.getLong(TIMESTAMP); String name = getOtherContact(localState, msg); boolean accept = msg.getBoolean(ACCEPT); diff --git a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java index d315313f8..065851270 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java @@ -29,7 +29,7 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ReadableMessageManagerImpl; import org.briarproject.util.StringUtils; import java.io.IOException; @@ -42,6 +42,8 @@ import java.util.logging.Logger; import javax.inject.Inject; import static java.util.logging.Level.WARNING; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.introduction.IntroduceeProtocolState.FINISHED; import static org.briarproject.api.introduction.IntroductionConstants.ACCEPT; import static org.briarproject.api.introduction.IntroductionConstants.ANSWERED; @@ -56,11 +58,9 @@ import static org.briarproject.api.introduction.IntroductionConstants.EXISTS; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2; -import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.MSG; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE; -import static org.briarproject.api.introduction.IntroductionConstants.READ; import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_ID; import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_IS_US; import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_1; @@ -76,7 +76,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; -class IntroductionManagerImpl extends BdfIncomingMessageHook +class IntroductionManagerImpl extends ReadableMessageManagerImpl implements IntroductionManager, Client, AddContactHook, RemoveContactHook { @@ -87,7 +87,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook private static final Logger LOG = Logger.getLogger(IntroductionManagerImpl.class.getName()); - private final DatabaseComponent db; private final IntroducerManager introducerManager; private final IntroduceeManager introduceeManager; private final IntroductionGroupFactory introductionGroupFactory; @@ -98,8 +97,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook IntroduceeManager introduceeManager, IntroductionGroupFactory introductionGroupFactory) { - super(clientHelper, metadataParser); - this.db = db; + super(clientHelper, db, metadataParser); this.introducerManager = introducerManager; this.introduceeManager = introduceeManager; this.introductionGroupFactory = introductionGroupFactory; @@ -166,8 +164,10 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook .getMessageMetadataAsDictionary(txn, gId, query); for (Map.Entry entry : map.entrySet()) { BdfDictionary d = entry.getValue(); - ContactId c1 = new ContactId(d.getLong(CONTACT_ID_1).intValue()); - ContactId c2 = new ContactId(d.getLong(CONTACT_ID_2).intValue()); + ContactId c1 = + new ContactId(d.getLong(CONTACT_ID_1).intValue()); + ContactId c2 = + new ContactId(d.getLong(CONTACT_ID_2).intValue()); if (c1.equals(c.getId()) || c2.equals(c.getId())) { IntroducerProtocolState state = IntroducerProtocolState @@ -198,7 +198,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook // remove the group (all messages will be removed with it) // this contact won't get our abort message, but the other will - db.removeGroup(txn, introductionGroupFactory.createIntroductionGroup(c)); + db.removeGroup(txn, + introductionGroupFactory.createIntroductionGroup(c)); + } + + @Override + protected Group getContactGroup(Contact c) { + return introductionGroupFactory.createIntroductionGroup(c); } /** @@ -207,8 +213,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook * in the introduction protocol and which engine we need to start. */ @Override - protected void incomingMessage(Transaction txn, Message m, BdfList body, - BdfDictionary message) throws DbException { + protected boolean incomingReadableMessage(Transaction txn, Message m, BdfList body, + BdfDictionary message) throws DbException, FormatException { // Get message data and type GroupId groupId = m.getGroupId(); @@ -218,7 +224,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook if (type == TYPE_REQUEST) { boolean stateExists = true; try { - getSessionState(txn, groupId, message.getRaw(SESSION_ID), false); + getSessionState(txn, groupId, message.getRaw(SESSION_ID), + false); } catch (FormatException e) { stateExists = false; } @@ -233,7 +240,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook LOG.log(WARNING, e.toString(), e); } deleteMessage(txn, m.getId()); - return; + return false; } try { introduceeManager.incomingMessage(txn, state, message); @@ -246,7 +253,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook } } // our role can be anything - else if (type == TYPE_RESPONSE || type == TYPE_ACK || type == TYPE_ABORT) { + else if (type == TYPE_RESPONSE || type == TYPE_ACK || + type == TYPE_ABORT) { BdfDictionary state; try { state = getSessionState(txn, groupId, @@ -254,7 +262,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook } catch (FormatException e) { LOG.warning("Could not find state for message, deleting..."); deleteMessage(txn, m.getId()); - return; + return false; } long role = state.getLong(ROLE, -1L); @@ -264,27 +272,35 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook } else if (role == ROLE_INTRODUCEE) { introduceeManager.incomingMessage(txn, state, message); } else { - if(LOG.isLoggable(WARNING)) { + if (LOG.isLoggable(WARNING)) { LOG.warning("Unknown role '" + role + "'. Deleting message..."); - deleteMessage(txn, m.getId()); } + deleteMessage(txn, m.getId()); + return false; } } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state); + if (role == ROLE_INTRODUCER) + introducerManager.abort(txn, state); else introduceeManager.abort(txn, state); } catch (IOException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state); + if (role == ROLE_INTRODUCER) + introducerManager.abort(txn, state); else introduceeManager.abort(txn, state); } } else { // the message has been validated, so this should not happen - if(LOG.isLoggable(WARNING)) { + if (LOG.isLoggable(WARNING)) { LOG.warning("Unknown message type '" + type + "', deleting..."); } + deleteMessage(txn, m.getId()); + return false; } + + // The message is valid + return true; } @Override @@ -374,14 +390,15 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook int role = state.getLong(ROLE).intValue(); boolean local; - long time = msg.getLong(MESSAGE_TIME); + long time = msg.getLong(TIMESTAMP); boolean accepted = msg.getBoolean(ACCEPT, false); boolean read = msg.getBoolean(READ, false); AuthorId authorId; String name; if (type == TYPE_RESPONSE) { if (role == ROLE_INTRODUCER) { - if (!concernsThisContact(contactId, messageId, state)) { + if (!concernsThisContact(contactId, messageId, + state)) { // this response is not from contactId continue; } @@ -445,7 +462,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook list.add(ir); } } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); } } txn.setComplete(); @@ -457,17 +475,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook return list; } - @Override - public void setReadFlag(MessageId m, boolean read) throws DbException { - try { - BdfDictionary meta = new BdfDictionary(); - meta.put(READ, read); - clientHelper.mergeMessageMetadata(m, meta); - } catch (FormatException e) { - throw new RuntimeException(e); - } - } - private String getNameForIntroducer(ContactId contactId, BdfDictionary state) throws FormatException { @@ -475,7 +482,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook return state.getString(CONTACT_2); if (contactId.getInt() == state.getLong(CONTACT_ID_2).intValue()) return state.getString(CONTACT_1); - throw new RuntimeException("Contact not part of this introduction session"); + throw new RuntimeException( + "Contact not part of this introduction session"); } private AuthorId getAuthorIdForIntroducer(ContactId contactId, @@ -485,10 +493,12 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook return new AuthorId(state.getRaw(AUTHOR_ID_2)); if (contactId.getInt() == state.getLong(CONTACT_ID_2).intValue()) return new AuthorId(state.getRaw(AUTHOR_ID_1)); - throw new RuntimeException("Contact not part of this introduction session"); + throw new RuntimeException( + "Contact not part of this introduction session"); } - private boolean concernsThisContact(ContactId contactId, MessageId messageId, + private boolean concernsThisContact(ContactId contactId, + MessageId messageId, BdfDictionary state) throws FormatException { if (contactId.getInt() == state.getLong(CONTACT_ID_1).intValue()) { @@ -520,7 +530,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook // to find state for introducee Map map = clientHelper .getMessageMetadataAsDictionary(txn, - introductionGroupFactory.createLocalGroup().getId()); + introductionGroupFactory.createLocalGroup() + .getId()); for (Map.Entry m : map.entrySet()) { if (Arrays.equals(m.getValue().getRaw(SESSION_ID), sessionId)) { BdfDictionary state = m.getValue(); diff --git a/briar-core/src/org/briarproject/introduction/IntroductionValidator.java b/briar-core/src/org/briarproject/introduction/IntroductionValidator.java index 7eacaccc8..c374534d9 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionValidator.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionValidator.java @@ -1,9 +1,9 @@ package org.briarproject.introduction; import org.briarproject.api.FormatException; +import org.briarproject.api.clients.BdfMessageContext; import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.SessionId; -import org.briarproject.api.clients.BdfMessageContext; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfList; import org.briarproject.api.data.MetadataEncoder; @@ -13,13 +13,15 @@ import org.briarproject.api.system.Clock; import org.briarproject.clients.BdfMessageValidator; import static org.briarproject.api.TransportId.MAX_TRANSPORT_ID_LENGTH; +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.introduction.IntroductionConstants.ACCEPT; import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_KEY; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_ID; -import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.MSG; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY; @@ -67,7 +69,9 @@ class IntroductionValidator extends BdfMessageValidator { d.put(SESSION_ID, id); d.put(GROUP_ID, m.getGroupId()); d.put(MESSAGE_ID, m.getId()); - d.put(MESSAGE_TIME, m.getTimestamp()); + d.put(TIMESTAMP, m.getTimestamp()); + d.put(LOCAL, false); + d.put(READ, false); return new BdfMessageContext(d); } diff --git a/briar-core/src/org/briarproject/introduction/MessageSender.java b/briar-core/src/org/briarproject/introduction/MessageSender.java index 9327dc9e2..c6e208bf4 100644 --- a/briar-core/src/org/briarproject/introduction/MessageSender.java +++ b/briar-core/src/org/briarproject/introduction/MessageSender.java @@ -16,10 +16,10 @@ import org.briarproject.api.system.Clock; import javax.inject.Inject; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.introduction.IntroductionConstants.ACCEPT; import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_KEY; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; -import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.MSG; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY; @@ -61,7 +61,7 @@ public class MessageSender { Group group = db.getGroup(txn, groupId); long timestamp = clock.currentTimeMillis(); - message.put(MESSAGE_TIME, timestamp); + message.put(TIMESTAMP, timestamp); Metadata metadata = metadataEncoder.encode(message); messageQueueManager diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java index 052df83c3..939d9a02f 100644 --- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java @@ -24,7 +24,7 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ReadableMessageManagerImpl; import org.briarproject.util.StringUtils; import java.util.ArrayList; @@ -33,23 +33,25 @@ import java.util.Map; import javax.inject.Inject; -class MessagingManagerImpl extends BdfIncomingMessageHook +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; + +class MessagingManagerImpl extends ReadableMessageManagerImpl implements MessagingManager, Client, AddContactHook, RemoveContactHook { static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( "6bcdc006c0910b0f44e40644c3b31f1a" + "8bf9a6d6021d40d219c86b731b903070")); - private final DatabaseComponent db; private final PrivateGroupFactory privateGroupFactory; @Inject MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, MetadataParser metadataParser, PrivateGroupFactory privateGroupFactory) { - super(clientHelper, metadataParser); + super(clientHelper, db, metadataParser); - this.db = db; this.privateGroupFactory = privateGroupFactory; } @@ -78,7 +80,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook } } - private Group getContactGroup(Contact c) { + @Override + protected Group getContactGroup(Contact c) { return privateGroupFactory.createPrivateGroup(CLIENT_ID, c); } @@ -93,30 +96,33 @@ class MessagingManagerImpl extends BdfIncomingMessageHook } @Override - protected void incomingMessage(Transaction txn, Message m, BdfList body, + protected boolean incomingReadableMessage(Transaction txn, Message m, BdfList body, BdfDictionary meta) throws DbException, FormatException { + // Broadcast event GroupId groupId = m.getGroupId(); - long timestamp = meta.getLong("timestamp"); + long timestamp = meta.getLong(TIMESTAMP); String contentType = meta.getString("contentType"); - boolean local = meta.getBoolean("local"); - boolean read = meta.getBoolean("read"); + boolean local = meta.getBoolean(LOCAL); + boolean read = meta.getBoolean(READ); PrivateMessageHeader header = new PrivateMessageHeader( m.getId(), timestamp, contentType, local, read, false, false); PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent( header, groupId); txn.attach(event); + + return true; } @Override public void addLocalMessage(PrivateMessage m) throws DbException { try { BdfDictionary meta = new BdfDictionary(); - meta.put("timestamp", m.getMessage().getTimestamp()); + meta.put(TIMESTAMP, m.getMessage().getTimestamp()); if (m.getParent() != null) meta.put("parent", m.getParent()); meta.put("contentType", m.getContentType()); - meta.put("local", true); - meta.put("read", true); + meta.put(LOCAL, true); + meta.put(READ, true); clientHelper.addLocalMessage(m.getMessage(), CLIENT_ID, meta, true); } catch (FormatException e) { throw new RuntimeException(e); @@ -169,10 +175,10 @@ class MessagingManagerImpl extends BdfIncomingMessageHook BdfDictionary meta = metadata.get(id); if (meta == null) continue; try { - long timestamp = meta.getLong("timestamp"); + long timestamp = meta.getLong(TIMESTAMP); String contentType = meta.getString("contentType"); - boolean local = meta.getBoolean("local"); - boolean read = meta.getBoolean("read"); + boolean local = meta.getBoolean(LOCAL); + boolean read = meta.getBoolean(READ); headers.add(new PrivateMessageHeader(id, timestamp, contentType, local, read, s.isSent(), s.isSeen())); } catch (FormatException e) { @@ -192,15 +198,4 @@ class MessagingManagerImpl extends BdfIncomingMessageHook throw new DbException(e); } } - - @Override - public void setReadFlag(MessageId m, boolean read) throws DbException { - try { - BdfDictionary meta = new BdfDictionary(); - meta.put("read", read); - clientHelper.mergeMessageMetadata(m, meta); - } catch (FormatException e) { - throw new RuntimeException(e); - } - } } diff --git a/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java b/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java index 74bd0d904..5c8f7efca 100644 --- a/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java +++ b/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java @@ -12,6 +12,9 @@ import org.briarproject.api.sync.Message; import org.briarproject.api.system.Clock; import org.briarproject.clients.BdfMessageValidator; +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; @@ -38,11 +41,11 @@ class PrivateMessageValidator extends BdfMessageValidator { checkLength(privateMessageBody, 0, MAX_PRIVATE_MESSAGE_BODY_LENGTH); // Return the metadata BdfDictionary meta = new BdfDictionary(); - meta.put("timestamp", m.getTimestamp()); + meta.put(TIMESTAMP, m.getTimestamp()); if (parentId != null) meta.put("parent", parentId); meta.put("contentType", contentType); - meta.put("local", false); - meta.put("read", false); + meta.put(LOCAL, false); + meta.put(READ, false); return new BdfMessageContext(meta); } } diff --git a/briar-core/src/org/briarproject/sharing/BlogSharingValidator.java b/briar-core/src/org/briarproject/sharing/BlogSharingValidator.java index 26b89bb52..4d5ca2969 100644 --- a/briar-core/src/org/briarproject/sharing/BlogSharingValidator.java +++ b/briar-core/src/org/briarproject/sharing/BlogSharingValidator.java @@ -16,21 +16,21 @@ import javax.inject.Inject; import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME; import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC; -import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY; +import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_DESC_LENGTH; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_TITLE_LENGTH; +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG; -import static org.briarproject.api.sharing.SharingConstants.LOCAL; import static org.briarproject.api.sharing.SharingConstants.SESSION_ID; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE; -import static org.briarproject.api.sharing.SharingConstants.TIME; import static org.briarproject.api.sharing.SharingConstants.TYPE; import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; @@ -92,7 +92,7 @@ class BlogSharingValidator extends BdfMessageValidator { d.put(TYPE, type); d.put(SESSION_ID, id); d.put(LOCAL, false); - d.put(TIME, m.getTimestamp()); + d.put(TIMESTAMP, m.getTimestamp()); return new BdfMessageContext(d); } } diff --git a/briar-core/src/org/briarproject/sharing/ForumSharingValidator.java b/briar-core/src/org/briarproject/sharing/ForumSharingValidator.java index 702466bea..1143c372c 100644 --- a/briar-core/src/org/briarproject/sharing/ForumSharingValidator.java +++ b/briar-core/src/org/briarproject/sharing/ForumSharingValidator.java @@ -14,19 +14,20 @@ import org.briarproject.clients.BdfMessageValidator; import javax.inject.Inject; +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH; import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH; import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG; -import static org.briarproject.api.sharing.SharingConstants.LOCAL; import static org.briarproject.api.sharing.SharingConstants.SESSION_ID; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE; -import static org.briarproject.api.sharing.SharingConstants.TIME; import static org.briarproject.api.sharing.SharingConstants.TYPE; import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; @@ -77,7 +78,8 @@ class ForumSharingValidator extends BdfMessageValidator { d.put(TYPE, type); d.put(SESSION_ID, id); d.put(LOCAL, false); - d.put(TIME, m.getTimestamp()); + d.put(TIMESTAMP, m.getTimestamp()); + d.put(READ, false); return new BdfMessageContext(d); } } diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java index 69be0d4b3..a002876df 100644 --- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java @@ -35,7 +35,7 @@ import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; import org.briarproject.api.system.Clock; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ReadableMessageManagerImpl; import org.briarproject.util.StringUtils; import java.io.IOException; @@ -53,10 +53,11 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.api.clients.ProtocolEngine.StateUpdate; +import static org.briarproject.api.clients.ReadableMessageConstants.LOCAL; +import static org.briarproject.api.clients.ReadableMessageConstants.READ; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.sharing.SharingConstants.CONTACT_ID; import static org.briarproject.api.sharing.SharingConstants.IS_SHARER; -import static org.briarproject.api.sharing.SharingConstants.LOCAL; -import static org.briarproject.api.sharing.SharingConstants.READ; import static org.briarproject.api.sharing.SharingConstants.SESSION_ID; import static org.briarproject.api.sharing.SharingConstants.SHAREABLE_ID; import static org.briarproject.api.sharing.SharingConstants.SHARED_BY_US; @@ -76,7 +77,6 @@ import static org.briarproject.api.sharing.SharingConstants.TASK_REMOVE_SHAREABL import static org.briarproject.api.sharing.SharingConstants.TASK_SHARE_SHAREABLE; import static org.briarproject.api.sharing.SharingConstants.TASK_UNSHARE_SHAREABLE_SHARED_BY_US; import static org.briarproject.api.sharing.SharingConstants.TASK_UNSHARE_SHAREABLE_SHARED_WITH_US; -import static org.briarproject.api.sharing.SharingConstants.TIME; import static org.briarproject.api.sharing.SharingConstants.TO_BE_SHARED_BY_US; import static org.briarproject.api.sharing.SharingConstants.TYPE; import static org.briarproject.api.sharing.SharingMessage.BaseMessage; @@ -84,14 +84,13 @@ import static org.briarproject.api.sharing.SharingMessage.Invitation; import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE; abstract class SharingManagerImpl - extends BdfIncomingMessageHook + extends ReadableMessageManagerImpl implements SharingManager, Client, AddContactHook, RemoveContactHook { private static final Logger LOG = Logger.getLogger(SharingManagerImpl.class.getName()); - private final DatabaseComponent db; private final MessageQueueManager messageQueueManager; private final MetadataEncoder metadataEncoder; private final SecureRandom random; @@ -105,8 +104,7 @@ abstract class SharingManagerImpl shareables) throws DbException, FormatException { + String key, List shareables) + throws DbException, FormatException { BdfList list = encodeShareableList(shareables); BdfDictionary metadata = BdfDictionary.of( diff --git a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java index c6a0afa45..a9ea32c3e 100644 --- a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java +++ b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java @@ -5,6 +5,7 @@ import org.briarproject.TestUtils; import org.briarproject.api.Bytes; import org.briarproject.api.FormatException; import org.briarproject.api.clients.ClientHelper; +import org.briarproject.api.clients.SessionId; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; @@ -19,7 +20,6 @@ import org.briarproject.api.identity.Author; import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.AuthorId; import org.briarproject.api.introduction.IntroduceeProtocolState; -import org.briarproject.api.clients.SessionId; import org.briarproject.api.properties.TransportPropertyManager; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.Group; @@ -34,6 +34,7 @@ import org.junit.Test; import java.security.SecureRandom; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.introduction.IntroduceeProtocolState.AWAIT_REQUEST; import static org.briarproject.api.introduction.IntroductionConstants.ACCEPT; @@ -46,7 +47,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; import static org.briarproject.api.introduction.IntroductionConstants.INTRODUCER; import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID; import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_ID; -import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY; @@ -63,7 +63,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; public class IntroduceeManagerTest extends BriarTestCase { @@ -164,7 +163,7 @@ public class IntroduceeManagerTest extends BriarTestCase { msg.put(GROUP_ID, introductionGroup1.getId()); msg.put(SESSION_ID, sessionId); msg.put(MESSAGE_ID, message1.getId()); - msg.put(MESSAGE_TIME, time); + msg.put(TIMESTAMP, time); msg.put(NAME, introducee2.getAuthor().getName()); msg.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey()); @@ -192,7 +191,7 @@ public class IntroduceeManagerTest extends BriarTestCase { msg.put(GROUP_ID, introductionGroup1.getId()); msg.put(SESSION_ID, sessionId); msg.put(MESSAGE_ID, message1.getId()); - msg.put(MESSAGE_TIME, time); + msg.put(TIMESTAMP, time); msg.put(NAME, introducee2.getAuthor().getName()); msg.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey()); diff --git a/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java b/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java index 9f4cc2174..8cd0022de 100644 --- a/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java +++ b/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import java.security.SecureRandom; +import static org.briarproject.api.clients.ReadableMessageConstants.TIMESTAMP; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.introduction.IntroducerProtocolState.AWAIT_RESPONSES; import static org.briarproject.api.introduction.IntroducerProtocolState.PREPARE_REQUESTS; @@ -39,7 +40,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2; -import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY; import static org.briarproject.api.introduction.IntroductionConstants.ROLE; @@ -136,7 +136,7 @@ public class IntroducerManagerTest extends BriarTestCase { msg1.put(NAME, state.getString(CONTACT_2)); msg1.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey()); final BdfDictionary msg1send = (BdfDictionary) msg1.clone(); - msg1send.put(MESSAGE_TIME, time); + msg1send.put(TIMESTAMP, time); final BdfDictionary msg2 = new BdfDictionary(); msg2.put(TYPE, TYPE_REQUEST); @@ -145,7 +145,7 @@ public class IntroducerManagerTest extends BriarTestCase { msg2.put(NAME, state.getString(CONTACT_1)); msg2.put(PUBLIC_KEY, introducee1.getAuthor().getPublicKey()); final BdfDictionary msg2send = (BdfDictionary) msg2.clone(); - msg2send.put(MESSAGE_TIME, time); + msg2send.put(TIMESTAMP, time); context.checking(new Expectations() {{ // initialize and store session state diff --git a/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java b/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java index 2b3bde49f..f6c63a0f7 100644 --- a/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java +++ b/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java @@ -248,7 +248,7 @@ public class IntroductionManagerImplTest extends BriarTestCase { }}); introductionManager - .incomingMessage(txn, message1, new BdfList(), msg); + .incomingReadableMessage(txn, message1, new BdfList(), msg); context.assertIsSatisfied(); assertFalse(txn.isComplete()); @@ -277,7 +277,7 @@ public class IntroductionManagerImplTest extends BriarTestCase { }}); introductionManager - .incomingMessage(txn, message1, new BdfList(), msg); + .incomingReadableMessage(txn, message1, new BdfList(), msg); context.assertIsSatisfied(); assertFalse(txn.isComplete());