Facade for private message headers. #173

This commit is contained in:
akwizgran
2015-12-17 16:04:45 +00:00
parent 87689855da
commit f899bc0c38
9 changed files with 147 additions and 50 deletions

View File

@@ -38,9 +38,9 @@ import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageAddedEvent; import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageHeader;
import java.util.Collection; import java.util.Collection;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -141,11 +141,11 @@ EventListener {
for (Contact c : contactManager.getContacts()) { for (Contact c : contactManager.getContacts()) {
try { try {
ContactId id = c.getId(); ContactId id = c.getId();
GroupId inbox = GroupId conversation =
messagingManager.getConversationId(id); messagingManager.getConversationId(id);
Collection<MessageHeader> headers = Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(id); messagingManager.getMessageHeaders(id);
displayContact(c, inbox, headers); displayContact(c, conversation, headers);
} catch (NoSuchContactException e) { } catch (NoSuchContactException e) {
// Continue // Continue
} }
@@ -174,8 +174,8 @@ EventListener {
}); });
} }
private void displayContact(final Contact c, private void displayContact(final Contact c, final GroupId conversation,
final GroupId inbox, final Collection<MessageHeader> headers) { final Collection<PrivateMessageHeader> headers) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
list.setVisibility(VISIBLE); list.setVisibility(VISIBLE);
@@ -185,7 +185,8 @@ EventListener {
ContactListItem item = findItem(c.getId()); ContactListItem item = findItem(c.getId());
if (item != null) adapter.remove(item); if (item != null) adapter.remove(item);
// Add a new item // Add a new item
adapter.add(new ContactListItem(c, connected, inbox, headers)); adapter.add(new ContactListItem(c, connected, conversation,
headers));
adapter.sort(ContactListItemComparator.INSTANCE); adapter.sort(ContactListItemComparator.INSTANCE);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
@@ -226,12 +227,12 @@ EventListener {
ContactListItem item = adapter.getItem(position); ContactListItem item = adapter.getItem(position);
ContactId contactId = item.getContact().getId(); ContactId contactId = item.getContact().getId();
String contactName = item.getContact().getAuthor().getName(); String contactName = item.getContact().getAuthor().getName();
GroupId inbox = item.getInboxGroupId(); GroupId groupId = item.getConversationId();
AuthorId localAuthorId = item.getContact().getLocalAuthorId(); AuthorId localAuthorId = item.getContact().getLocalAuthorId();
Intent i = new Intent(this, ConversationActivity.class); Intent i = new Intent(this, ConversationActivity.class);
i.putExtra("briar.CONTACT_ID", contactId.getInt()); i.putExtra("briar.CONTACT_ID", contactId.getInt());
i.putExtra("briar.CONTACT_NAME", contactName); i.putExtra("briar.CONTACT_NAME", contactName);
i.putExtra("briar.GROUP_ID", inbox.getBytes()); i.putExtra("briar.GROUP_ID", groupId.getBytes());
i.putExtra("briar.LOCAL_AUTHOR_ID", localAuthorId.getBytes()); i.putExtra("briar.LOCAL_AUTHOR_ID", localAuthorId.getBytes());
startActivity(i); startActivity(i);
} }
@@ -293,7 +294,7 @@ EventListener {
public void run() { public void run() {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
Collection<MessageHeader> headers = Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(c); messagingManager.getMessageHeaders(c);
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
@@ -310,7 +311,7 @@ EventListener {
} }
private void updateItem(final ContactId c, private void updateItem(final ContactId c,
final Collection<MessageHeader> headers) { final Collection<PrivateMessageHeader> headers) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
ContactListItem item = findItem(c); ContactListItem item = findItem(c);

View File

@@ -1,8 +1,8 @@
package org.briarproject.android.contact; package org.briarproject.android.contact;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageHeader;
import java.util.Collection; import java.util.Collection;
@@ -10,25 +10,25 @@ import java.util.Collection;
class ContactListItem { class ContactListItem {
private final Contact contact; private final Contact contact;
private final GroupId inbox; private final GroupId conversation;
private boolean connected, empty; private boolean connected, empty;
private long timestamp; private long timestamp;
private int unread; private int unread;
ContactListItem(Contact contact, boolean connected, GroupId inbox, ContactListItem(Contact contact, boolean connected, GroupId conversation,
Collection<MessageHeader> headers) { Collection<PrivateMessageHeader> headers) {
this.contact = contact; this.contact = contact;
this.inbox = inbox; this.conversation = conversation;
this.connected = connected; this.connected = connected;
setHeaders(headers); setHeaders(headers);
} }
void setHeaders(Collection<MessageHeader> headers) { void setHeaders(Collection<PrivateMessageHeader> headers) {
empty = headers.isEmpty(); empty = headers.isEmpty();
timestamp = 0; timestamp = 0;
unread = 0; unread = 0;
if (!empty) { if (!empty) {
for (MessageHeader h : headers) { for (PrivateMessageHeader h : headers) {
if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp(); if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp();
if (!h.isRead()) unread++; if (!h.isRead()) unread++;
} }
@@ -39,8 +39,8 @@ class ContactListItem {
return contact; return contact;
} }
GroupId getInboxGroupId() { GroupId getConversationId() {
return inbox; return conversation;
} }
boolean isConnected() { boolean isConnected() {

View File

@@ -41,11 +41,11 @@ import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateConversation; import org.briarproject.api.messaging.PrivateConversation;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.messaging.PrivateMessageHeader.Status;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageHeader;
import org.briarproject.api.sync.MessageHeader.State;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
@@ -70,6 +70,8 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.android.contact.ReadPrivateMessageActivity.RESULT_PREV_NEXT; import static org.briarproject.android.contact.ReadPrivateMessageActivity.RESULT_PREV_NEXT;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
import static org.briarproject.api.messaging.PrivateMessageHeader.Status.DELIVERED;
import static org.briarproject.api.messaging.PrivateMessageHeader.Status.SENT;
public class ConversationActivity extends BriarActivity public class ConversationActivity extends BriarActivity
implements EventListener, OnClickListener, OnItemClickListener { implements EventListener, OnClickListener, OnItemClickListener {
@@ -209,7 +211,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
public void run() { public void run() {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
Collection<MessageHeader> headers = Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(contactId); messagingManager.getMessageHeaders(contactId);
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
@@ -225,7 +227,8 @@ implements EventListener, OnClickListener, OnItemClickListener {
}); });
} }
private void displayHeaders(final Collection<MessageHeader> headers) { private void displayHeaders(
final Collection<PrivateMessageHeader> headers) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
loading.setVisibility(GONE); loading.setVisibility(GONE);
@@ -235,7 +238,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
sendButton.setEnabled(true); sendButton.setEnabled(true);
adapter.clear(); adapter.clear();
if (!headers.isEmpty()) { if (!headers.isEmpty()) {
for (MessageHeader h : headers) { for (PrivateMessageHeader h : headers) {
ConversationItem item = new ConversationItem(h); ConversationItem item = new ConversationItem(h);
byte[] body = bodyCache.get(h.getId()); byte[] body = bodyCache.get(h.getId());
if (body == null) loadMessageBody(h); if (body == null) loadMessageBody(h);
@@ -251,7 +254,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
}); });
} }
private void loadMessageBody(final MessageHeader h) { private void loadMessageBody(final PrivateMessageHeader h) {
runOnDbThread(new Runnable() { runOnDbThread(new Runnable() {
public void run() { public void run() {
try { try {
@@ -312,7 +315,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
List<MessageId> unread = new ArrayList<MessageId>(); List<MessageId> unread = new ArrayList<MessageId>();
int count = adapter.getCount(); int count = adapter.getCount();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
MessageHeader h = adapter.getItem(i).getHeader(); PrivateMessageHeader h = adapter.getItem(i).getHeader();
if (!h.isRead()) unread.add(h.getId()); if (!h.isRead()) unread.add(h.getId());
} }
if (unread.isEmpty()) return; if (unread.isEmpty()) return;
@@ -356,13 +359,13 @@ implements EventListener, OnClickListener, OnItemClickListener {
MessagesSentEvent m = (MessagesSentEvent) e; MessagesSentEvent m = (MessagesSentEvent) e;
if (m.getContactId().equals(contactId)) { if (m.getContactId().equals(contactId)) {
LOG.info("Messages sent"); LOG.info("Messages sent");
markMessages(m.getMessageIds(), State.SENT); markMessages(m.getMessageIds(), SENT);
} }
} else if (e instanceof MessagesAckedEvent) { } else if (e instanceof MessagesAckedEvent) {
MessagesAckedEvent m = (MessagesAckedEvent) e; MessagesAckedEvent m = (MessagesAckedEvent) e;
if (m.getContactId().equals(contactId)) { if (m.getContactId().equals(contactId)) {
LOG.info("Messages acked"); LOG.info("Messages acked");
markMessages(m.getMessageIds(), State.DELIVERED); markMessages(m.getMessageIds(), DELIVERED);
} }
} else if (e instanceof ContactConnectedEvent) { } else if (e instanceof ContactConnectedEvent) {
ContactConnectedEvent c = (ContactConnectedEvent) e; ContactConnectedEvent c = (ContactConnectedEvent) e;
@@ -381,7 +384,8 @@ implements EventListener, OnClickListener, OnItemClickListener {
} }
} }
private void markMessages(final Collection<MessageId> messageIds, final State state) { private void markMessages(final Collection<MessageId> messageIds,
final Status status) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
Set<MessageId> messages = new HashSet<MessageId>(messageIds); Set<MessageId> messages = new HashSet<MessageId>(messageIds);
@@ -390,7 +394,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
ConversationItem item = adapter.getItem(i); ConversationItem item = adapter.getItem(i);
if (messages.contains(item.getHeader().getId())) { if (messages.contains(item.getHeader().getId())) {
item.setStatus(state); item.setStatus(status);
changed = true; changed = true;
} }
} }
@@ -460,7 +464,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
private void displayMessage(int position) { private void displayMessage(int position) {
ConversationItem item = adapter.getItem(position); ConversationItem item = adapter.getItem(position);
MessageHeader header = item.getHeader(); PrivateMessageHeader header = item.getHeader();
Intent i = new Intent(this, ReadPrivateMessageActivity.class); Intent i = new Intent(this, ReadPrivateMessageActivity.class);
i.putExtra("briar.CONTACT_ID", contactId.getInt()); i.putExtra("briar.CONTACT_ID", contactId.getInt());
i.putExtra("briar.CONTACT_NAME", contactName); i.putExtra("briar.CONTACT_NAME", contactName);

View File

@@ -14,8 +14,7 @@ import android.widget.TextView;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.util.ElasticHorizontalSpace; import org.briarproject.android.util.ElasticHorizontalSpace;
import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.LayoutUtils;
import org.briarproject.api.sync.MessageHeader; import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.MessageHeader.State;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
@@ -25,6 +24,8 @@ import static android.view.Gravity.LEFT;
import static android.widget.LinearLayout.HORIZONTAL; import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL; import static android.widget.LinearLayout.VERTICAL;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.api.messaging.PrivateMessageHeader.Status.DELIVERED;
import static org.briarproject.api.messaging.PrivateMessageHeader.Status.SENT;
class ConversationAdapter extends ArrayAdapter<ConversationItem> { class ConversationAdapter extends ArrayAdapter<ConversationItem> {
@@ -39,7 +40,7 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
ConversationItem item = getItem(position); ConversationItem item = getItem(position);
MessageHeader header = item.getHeader(); PrivateMessageHeader header = item.getHeader();
Context ctx = getContext(); Context ctx = getContext();
Resources res = ctx.getResources(); Resources res = ctx.getResources();
@@ -81,9 +82,9 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
ImageView status = new ImageView(ctx); ImageView status = new ImageView(ctx);
status.setPadding(0, 0, pad, 0); status.setPadding(0, 0, pad, 0);
if (item.getStatus() == State.DELIVERED) { if (item.getStatus() == DELIVERED) {
status.setImageResource(R.drawable.message_delivered); status.setImageResource(R.drawable.message_delivered);
} else if (item.getStatus() == State.SENT) { } else if (item.getStatus() == SENT) {
status.setImageResource(R.drawable.message_sent); status.setImageResource(R.drawable.message_sent);
} else { } else {
status.setImageResource(R.drawable.message_stored); status.setImageResource(R.drawable.message_stored);

View File

@@ -1,22 +1,22 @@
package org.briarproject.android.contact; package org.briarproject.android.contact;
import org.briarproject.api.sync.MessageHeader; import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.MessageHeader.State; import org.briarproject.api.messaging.PrivateMessageHeader.Status;
// This class is not thread-safe // This class is not thread-safe
class ConversationItem { class ConversationItem {
private final MessageHeader header; private final PrivateMessageHeader header;
private byte[] body; private byte[] body;
private State status; private Status status;
ConversationItem(MessageHeader header) { ConversationItem(PrivateMessageHeader header) {
this.header = header; this.header = header;
body = null; body = null;
status = header.getStatus(); status = header.getStatus();
} }
MessageHeader getHeader() { PrivateMessageHeader getHeader() {
return header; return header;
} }
@@ -28,11 +28,11 @@ class ConversationItem {
this.body = body; this.body = body;
} }
State getStatus() { Status getStatus() {
return status; return status;
} }
void setStatus(State state) { void setStatus(Status status) {
this.status = state; this.status = status;
} }
} }

View File

@@ -4,7 +4,6 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageHeader;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import java.util.Collection; import java.util.Collection;
@@ -27,7 +26,7 @@ public interface MessagingManager {
* Returns the headers of all messages in the private conversation with the * Returns the headers of all messages in the private conversation with the
* given contact, or null if no private conversation ID has been set. * given contact, or null if no private conversation ID has been set.
*/ */
Collection<MessageHeader> getMessageHeaders(ContactId c) Collection<PrivateMessageHeader> getMessageHeaders(ContactId c)
throws DbException; throws DbException;
/** Returns the body of the private message with the given ID. */ /** Returns the body of the private message with the given ID. */

View File

@@ -0,0 +1,23 @@
package org.briarproject.api.messaging;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.MessageId;
public interface PrivateMessageHeader {
enum Status { STORED, SENT, DELIVERED }
MessageId getId();
Author getAuthor();
String getContentType();
long getTimestamp();
boolean isLocal();
boolean isRead();
Status getStatus();
}

View File

@@ -7,12 +7,16 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateConversation; import org.briarproject.api.messaging.PrivateConversation;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageHeader; import org.briarproject.api.sync.MessageHeader;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
// Temporary facade during sync protocol refactoring // Temporary facade during sync protocol refactoring
class MessagingManagerImpl implements MessagingManager { class MessagingManagerImpl implements MessagingManager {
@@ -40,9 +44,14 @@ class MessagingManagerImpl implements MessagingManager {
} }
@Override @Override
public Collection<MessageHeader> getMessageHeaders(ContactId c) public Collection<PrivateMessageHeader> getMessageHeaders(ContactId c)
throws DbException { throws DbException {
return db.getInboxMessageHeaders(c); Collection<MessageHeader> headers = db.getInboxMessageHeaders(c);
List<PrivateMessageHeader> privateHeaders =
new ArrayList<PrivateMessageHeader>(headers.size());
for (MessageHeader m : headers)
privateHeaders.add(new PrivateMessageHeaderImpl(m));
return Collections.unmodifiableList(privateHeaders);
} }
@Override @Override

View File

@@ -0,0 +1,60 @@
package org.briarproject.messaging;
import org.briarproject.api.identity.Author;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.MessageHeader;
import org.briarproject.api.sync.MessageId;
// Temporary facade during sync protocol refactoring
public class PrivateMessageHeaderImpl implements PrivateMessageHeader {
private final MessageHeader messageHeader;
PrivateMessageHeaderImpl(MessageHeader messageHeader) {
this.messageHeader = messageHeader;
}
@Override
public MessageId getId() {
return messageHeader.getId();
}
@Override
public Author getAuthor() {
return messageHeader.getAuthor();
}
@Override
public String getContentType() {
return messageHeader.getContentType();
}
@Override
public long getTimestamp() {
return messageHeader.getTimestamp();
}
@Override
public boolean isLocal() {
return messageHeader.isLocal();
}
@Override
public boolean isRead() {
return messageHeader.isRead();
}
@Override
public Status getStatus() {
switch (messageHeader.getStatus()) {
case STORED:
return Status.STORED;
case SENT:
return Status.SENT;
case DELIVERED:
return Status.DELIVERED;
default:
throw new IllegalStateException();
}
}
}