Don't use messaging group ID as proxy for contact ID.

This commit is contained in:
akwizgran
2016-10-18 14:14:15 +01:00
parent e0f4be931d
commit 51bcf7b1b8
15 changed files with 139 additions and 168 deletions

View File

@@ -34,7 +34,6 @@ import org.briarproject.api.event.PrivateMessageReceivedEvent;
import org.briarproject.api.event.SettingsUpdatedEvent; import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.lifecycle.Service; import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.lifecycle.ServiceException; import org.briarproject.api.lifecycle.ServiceException;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.settings.Settings; import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.settings.SettingsManager;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
@@ -65,6 +64,7 @@ import static org.briarproject.android.BriarActivity.GROUP_ID;
import static org.briarproject.android.NavDrawerActivity.INTENT_BLOGS; import static org.briarproject.android.NavDrawerActivity.INTENT_BLOGS;
import static org.briarproject.android.NavDrawerActivity.INTENT_CONTACTS; import static org.briarproject.android.NavDrawerActivity.INTENT_CONTACTS;
import static org.briarproject.android.NavDrawerActivity.INTENT_FORUMS; import static org.briarproject.android.NavDrawerActivity.INTENT_FORUMS;
import static org.briarproject.android.contact.ConversationActivity.CONTACT_ID;
import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_BLOG; import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_BLOG;
import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
@@ -100,19 +100,19 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private final Executor dbExecutor; private final Executor dbExecutor;
private final SettingsManager settingsManager; private final SettingsManager settingsManager;
private final MessagingManager messagingManager;
private final AndroidExecutor androidExecutor; private final AndroidExecutor androidExecutor;
private final Context appContext; private final Context appContext;
private final BroadcastReceiver receiver = new DeleteIntentReceiver(); private final BroadcastReceiver receiver = new DeleteIntentReceiver();
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
// The following must only be accessed on the main UI thread // The following must only be accessed on the main UI thread
private final Map<GroupId, Integer> contactCounts = new HashMap<>(); private final Map<ContactId, Integer> contactCounts = new HashMap<>();
private final Map<GroupId, Integer> forumCounts = new HashMap<>(); private final Map<GroupId, Integer> forumCounts = new HashMap<>();
private final Map<GroupId, Integer> blogCounts = new HashMap<>(); private final Map<GroupId, Integer> blogCounts = new HashMap<>();
private int contactTotal = 0, forumTotal = 0, blogTotal = 0; private int contactTotal = 0, forumTotal = 0, blogTotal = 0;
private int introductionTotal = 0; private int introductionTotal = 0;
private int nextRequestId = 0; private int nextRequestId = 0;
private ContactId blockedContact = null;
private GroupId blockedGroup = null; private GroupId blockedGroup = null;
private boolean blockContacts = false, blockForums = false; private boolean blockContacts = false, blockForums = false;
private boolean blockBlogs = false, blockIntroductions = false; private boolean blockBlogs = false, blockIntroductions = false;
@@ -121,11 +121,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Inject @Inject
AndroidNotificationManagerImpl(@DatabaseExecutor Executor dbExecutor, AndroidNotificationManagerImpl(@DatabaseExecutor Executor dbExecutor,
SettingsManager settingsManager, MessagingManager messagingManager, SettingsManager settingsManager, AndroidExecutor androidExecutor,
AndroidExecutor androidExecutor, Application app) { Application app) {
this.dbExecutor = dbExecutor; this.dbExecutor = dbExecutor;
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
this.messagingManager = messagingManager;
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
appContext = app.getApplicationContext(); appContext = app.getApplicationContext();
} }
@@ -165,7 +164,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Future<Void> f = androidExecutor.runOnUiThread(new Callable<Void>() { Future<Void> f = androidExecutor.runOnUiThread(new Callable<Void>() {
@Override @Override
public Void call() { public Void call() {
clearPrivateMessageNotification(); clearContactNotification();
clearForumPostNotification(); clearForumPostNotification();
clearBlogPostNotification(); clearBlogPostNotification();
clearIntroductionSuccessNotification(); clearIntroductionSuccessNotification();
@@ -181,7 +180,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} }
@UiThread @UiThread
private void clearPrivateMessageNotification() { private void clearContactNotification() {
contactCounts.clear(); contactCounts.clear();
contactTotal = 0; contactTotal = 0;
Object o = appContext.getSystemService(NOTIFICATION_SERVICE); Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
@@ -222,7 +221,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
if (s.getNamespace().equals(SETTINGS_NAMESPACE)) loadSettings(); if (s.getNamespace().equals(SETTINGS_NAMESPACE)) loadSettings();
} else if (e instanceof PrivateMessageReceivedEvent) { } else if (e instanceof PrivateMessageReceivedEvent) {
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
showPrivateMessageNotification(p.getGroupId()); showContactNotification(p.getContactId());
} else if (e instanceof ForumPostReceivedEvent) { } else if (e instanceof ForumPostReceivedEvent) {
ForumPostReceivedEvent f = (ForumPostReceivedEvent) e; ForumPostReceivedEvent f = (ForumPostReceivedEvent) e;
showForumPostNotification(f.getGroupId()); showForumPostNotification(f.getGroupId());
@@ -231,16 +230,17 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
showBlogPostNotification(b.getGroupId()); showBlogPostNotification(b.getGroupId());
} else if (e instanceof IntroductionRequestReceivedEvent) { } else if (e instanceof IntroductionRequestReceivedEvent) {
ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId(); ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId();
showNotificationForPrivateConversation(c); showContactNotification(c);
} else if (e instanceof IntroductionResponseReceivedEvent) { } else if (e instanceof IntroductionResponseReceivedEvent) {
ContactId c = ((IntroductionResponseReceivedEvent) e).getContactId(); ContactId c =
showNotificationForPrivateConversation(c); ((IntroductionResponseReceivedEvent) e).getContactId();
showContactNotification(c);
} else if (e instanceof InvitationRequestReceivedEvent) { } else if (e instanceof InvitationRequestReceivedEvent) {
ContactId c = ((InvitationRequestReceivedEvent) e).getContactId(); ContactId c = ((InvitationRequestReceivedEvent) e).getContactId();
showNotificationForPrivateConversation(c); showContactNotification(c);
} else if (e instanceof InvitationResponseReceivedEvent) { } else if (e instanceof InvitationResponseReceivedEvent) {
ContactId c = ((InvitationResponseReceivedEvent) e).getContactId(); ContactId c = ((InvitationResponseReceivedEvent) e).getContactId();
showNotificationForPrivateConversation(c); showContactNotification(c);
} else if (e instanceof IntroductionSucceededEvent) { } else if (e instanceof IntroductionSucceededEvent) {
showIntroductionNotification(); showIntroductionNotification();
} }
@@ -260,38 +260,38 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
private void showPrivateMessageNotification(final GroupId g) { private void showContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if (blockContacts) return; if (blockContacts) return;
if (g.equals(blockedGroup)) return; if (c.equals(blockedContact)) return;
Integer count = contactCounts.get(g); Integer count = contactCounts.get(c);
if (count == null) contactCounts.put(g, 1); if (count == null) contactCounts.put(c, 1);
else contactCounts.put(g, count + 1); else contactCounts.put(c, count + 1);
contactTotal++; contactTotal++;
updatePrivateMessageNotification(); updateContactNotification();
} }
}); });
} }
@Override @Override
public void clearPrivateMessageNotification(final GroupId g) { public void clearContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
Integer count = contactCounts.remove(g); Integer count = contactCounts.remove(c);
if (count == null) return; // Already cleared if (count == null) return; // Already cleared
contactTotal -= count; contactTotal -= count;
updatePrivateMessageNotification(); updateContactNotification();
} }
}); });
} }
@UiThread @UiThread
private void updatePrivateMessageNotification() { private void updateContactNotification() {
if (contactTotal == 0) { if (contactTotal == 0) {
clearPrivateMessageNotification(); clearContactNotification();
} else if (settings.getBoolean("notifyPrivateMessages", true)) { } else if (settings.getBoolean("notifyPrivateMessages", true)) {
NotificationCompat.Builder b = NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext); new NotificationCompat.Builder(appContext);
@@ -315,10 +315,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
if (contactCounts.size() == 1) { if (contactCounts.size() == 1) {
// Touching the notification shows the relevant conversation // Touching the notification shows the relevant conversation
Intent i = new Intent(appContext, ConversationActivity.class); Intent i = new Intent(appContext, ConversationActivity.class);
GroupId g = contactCounts.keySet().iterator().next(); ContactId c = contactCounts.keySet().iterator().next();
i.putExtra(GROUP_ID, g.getBytes()); i.putExtra(CONTACT_ID, c.getInt());
String idHex = StringUtils.toHexString(g.getBytes()); i.setData(Uri.parse(CONTACT_URI + "/" + c.getInt()));
i.setData(Uri.parse(CONTACT_URI + "/" + idHex));
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder t = TaskStackBuilder.create(appContext); TaskStackBuilder t = TaskStackBuilder.create(appContext);
t.addParentStack(ConversationActivity.class); t.addParentStack(ConversationActivity.class);
@@ -362,7 +361,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
clearPrivateMessageNotification(); clearContactNotification();
clearIntroductionSuccessNotification(); clearIntroductionSuccessNotification();
} }
}); });
@@ -613,6 +612,26 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
@Override
public void blockContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() {
@Override
public void run() {
blockedContact = c;
}
});
}
@Override
public void unblockContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() {
@Override
public void run() {
if (c.equals(blockedContact)) blockedContact = null;
}
});
}
@Override @Override
public void blockAllContactNotifications() { public void blockAllContactNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(new Runnable() {
@@ -675,21 +694,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
private void showNotificationForPrivateConversation(final ContactId c) {
dbExecutor.execute(new Runnable() {
@Override
public void run() {
try {
GroupId g = messagingManager.getConversationId(c);
showPrivateMessageNotification(g);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
private class DeleteIntentReceiver extends BroadcastReceiver { private class DeleteIntentReceiver extends BroadcastReceiver {
@Override @Override
@@ -699,7 +703,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void run() { public void run() {
if (CLEAR_PRIVATE_MESSAGE_ACTION.equals(action)) { if (CLEAR_PRIVATE_MESSAGE_ACTION.equals(action)) {
clearPrivateMessageNotification(); clearContactNotification();
} else if (CLEAR_FORUM_ACTION.equals(action)) { } else if (CLEAR_FORUM_ACTION.equals(action)) {
clearForumPostNotification(); clearForumPostNotification();
} else if (CLEAR_BLOG_ACTION.equals(action)) { } else if (CLEAR_BLOG_ACTION.equals(action)) {

View File

@@ -1,5 +1,6 @@
package org.briarproject.android.api; package org.briarproject.android.api;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
/** /**
@@ -8,7 +9,7 @@ import org.briarproject.api.sync.GroupId;
*/ */
public interface AndroidNotificationManager { public interface AndroidNotificationManager {
void clearPrivateMessageNotification(GroupId g); void clearContactNotification(ContactId c);
void clearAllContactNotifications(); void clearAllContactNotifications();
@@ -20,6 +21,10 @@ public interface AndroidNotificationManager {
void clearAllBlogPostNotifications(); void clearAllBlogPostNotifications();
void blockContactNotification(ContactId c);
void unblockContactNotification(ContactId c);
void blockNotification(GroupId g); void blockNotification(GroupId g);
void unblockNotification(GroupId g); void unblockNotification(GroupId g);

View File

@@ -10,6 +10,7 @@ import javax.annotation.concurrent.NotThreadSafe;
public class ContactItem { public class ContactItem {
private final Contact contact; private final Contact contact;
private boolean connected; private boolean connected;
public ContactItem(Contact contact, boolean connected) { public ContactItem(Contact contact, boolean connected) {

View File

@@ -48,7 +48,6 @@ import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sharing.InvitationRequest;
import org.briarproject.api.sharing.InvitationResponse; import org.briarproject.api.sharing.InvitationResponse;
import org.briarproject.api.sync.GroupId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -60,7 +59,7 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
import static android.support.v4.view.ViewCompat.getTransitionName; import static android.support.v4.view.ViewCompat.getTransitionName;
import static java.util.logging.Level.INFO; 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.BriarActivity.GROUP_ID; import static org.briarproject.android.contact.ConversationActivity.CONTACT_ID;
public class ContactListFragment extends BaseFragment implements EventListener { public class ContactListFragment extends BaseFragment implements EventListener {
@@ -111,10 +110,10 @@ public class ContactListFragment extends BaseFragment implements EventListener {
new OnContactClickListener<ContactListItem>() { new OnContactClickListener<ContactListItem>() {
@Override @Override
public void onItemClick(View view, ContactListItem item) { public void onItemClick(View view, ContactListItem item) {
GroupId groupId = item.getGroupId();
Intent i = new Intent(getActivity(), Intent i = new Intent(getActivity(),
ConversationActivity.class); ConversationActivity.class);
i.putExtra(GROUP_ID, groupId.getBytes()); ContactId contactId = item.getContact().getId();
i.putExtra(CONTACT_ID, contactId.getInt());
// work-around for android bug #224270 // work-around for android bug #224270
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
@@ -200,14 +199,12 @@ public class ContactListFragment extends BaseFragment implements EventListener {
for (Contact c : contactManager.getActiveContacts()) { for (Contact c : contactManager.getActiveContacts()) {
try { try {
ContactId id = c.getId(); ContactId id = c.getId();
GroupId groupId =
conversationManager.getConversationId(id);
GroupCount count = GroupCount count =
conversationManager.getGroupCount(id); conversationManager.getGroupCount(id);
boolean connected = boolean connected =
connectionRegistry.isConnected(c.getId()); connectionRegistry.isConnected(c.getId());
contacts.add(new ContactListItem(c, connected, contacts.add(new ContactListItem(c, connected,
groupId, count)); count));
} catch (NoSuchContactException e) { } catch (NoSuchContactException e) {
// Continue // Continue
} }

View File

@@ -3,7 +3,6 @@ package org.briarproject.android.contact;
import org.briarproject.api.clients.MessageTracker.GroupCount; import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
@@ -11,15 +10,13 @@ import javax.annotation.concurrent.NotThreadSafe;
@NotNullByDefault @NotNullByDefault
public class ContactListItem extends ContactItem { public class ContactListItem extends ContactItem {
private final GroupId groupId;
private boolean empty; private boolean empty;
private long timestamp; private long timestamp;
private int unread; private int unread;
public ContactListItem(Contact contact, boolean connected, GroupId groupId, public ContactListItem(Contact contact, boolean connected,
GroupCount count) { GroupCount count) {
super(contact, connected); super(contact, connected);
this.groupId = groupId;
this.empty = count.getMsgCount() == 0; this.empty = count.getMsgCount() == 0;
this.unread = count.getUnreadCount(); this.unread = count.getUnreadCount();
this.timestamp = count.getLatestMsgTime(); this.timestamp = count.getLatestMsgTime();
@@ -32,10 +29,6 @@ public class ContactListItem extends ContactItem {
unread++; unread++;
} }
GroupId getGroupId() {
return groupId;
}
boolean isEmpty() { boolean isEmpty() {
return empty; return empty;
} }

View File

@@ -7,13 +7,13 @@ import android.widget.TextView;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener; import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import static android.support.v4.view.ViewCompat.setTransitionName; import static android.support.v4.view.ViewCompat.setTransitionName;
import static org.briarproject.android.util.AndroidUtils.formatDate; import static org.briarproject.android.util.AndroidUtils.formatDate;
import static org.briarproject.util.StringUtils.toHexString;
@UiThread @UiThread
@NotNullByDefault @NotNullByDefault
@@ -23,7 +23,7 @@ class ContactListItemViewHolder extends ContactItemViewHolder<ContactListItem> {
private final TextView unread; private final TextView unread;
private final TextView date; private final TextView date;
public ContactListItemViewHolder(View v) { ContactListItemViewHolder(View v) {
super(v); super(v);
bulb = (ImageView) v.findViewById(R.id.bulbView); bulb = (ImageView) v.findViewById(R.id.bulbView);
unread = (TextView) v.findViewById(R.id.unreadCountView); unread = (TextView) v.findViewById(R.id.unreadCountView);
@@ -59,16 +59,9 @@ class ContactListItemViewHolder extends ContactItemViewHolder<ContactListItem> {
bulb.setImageResource(R.drawable.contact_disconnected); bulb.setImageResource(R.drawable.contact_disconnected);
} }
setTransitionName(avatar, getAvatarTransitionName(item.getGroupId())); ContactId c = item.getContact().getId();
setTransitionName(bulb, getBulbTransitionName(item.getGroupId())); setTransitionName(avatar, AndroidUtils.getAvatarTransitionName(c));
} setTransitionName(bulb, AndroidUtils.getBulbTransitionName(c));
private String getAvatarTransitionName(GroupId g) {
return "avatar" + toHexString(g.getBytes());
}
private String getBulbTransitionName(GroupId g) {
return "bulb" + toHexString(g.getBytes());
} }
} }

View File

@@ -30,6 +30,7 @@ import org.briarproject.android.BriarActivity;
import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.contact.ConversationAdapter.RequestListener; import org.briarproject.android.contact.ConversationAdapter.RequestListener;
import org.briarproject.android.introduction.IntroductionActivity; import org.briarproject.android.introduction.IntroductionActivity;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.android.view.BriarRecyclerView; import org.briarproject.android.view.BriarRecyclerView;
import org.briarproject.android.view.TextInputView; import org.briarproject.android.view.TextInputView;
import org.briarproject.android.view.TextInputView.TextInputListener; import org.briarproject.android.view.TextInputView.TextInputListener;
@@ -57,6 +58,7 @@ import org.briarproject.api.event.MessagesAckedEvent;
import org.briarproject.api.event.MessagesSentEvent; import org.briarproject.api.event.MessagesSentEvent;
import org.briarproject.api.event.PrivateMessageReceivedEvent; import org.briarproject.api.event.PrivateMessageReceivedEvent;
import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.introduction.IntroductionManager; import org.briarproject.api.introduction.IntroductionManager;
import org.briarproject.api.introduction.IntroductionMessage; import org.briarproject.api.introduction.IntroductionMessage;
import org.briarproject.api.introduction.IntroductionRequest; import org.briarproject.api.introduction.IntroductionRequest;
@@ -73,6 +75,7 @@ import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sharing.InvitationRequest;
import org.briarproject.api.sharing.InvitationResponse; import org.briarproject.api.sharing.InvitationResponse;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -106,6 +109,8 @@ import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESS
public class ConversationActivity extends BriarActivity public class ConversationActivity extends BriarActivity
implements EventListener, RequestListener, TextInputListener { implements EventListener, RequestListener, TextInputListener {
public static final String CONTACT_ID = "briar.CONTACT_ID";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(ConversationActivity.class.getName()); Logger.getLogger(ConversationActivity.class.getName());
private static final int REQUEST_CODE_INTRODUCTION = 1; private static final int REQUEST_CODE_INTRODUCTION = 1;
@@ -150,10 +155,10 @@ public class ConversationActivity extends BriarActivity
@Inject @Inject
volatile GroupInvitationManager groupInvitationManager; volatile GroupInvitationManager groupInvitationManager;
private volatile GroupId groupId = null; private volatile ContactId contactId;
private volatile ContactId contactId = null; private volatile String contactName;
private volatile String contactName = null; private volatile AuthorId contactAuthorId;
private volatile byte[] contactIdenticonKey = null; private volatile GroupId messagingGroupId;
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@Override @Override
@@ -161,9 +166,9 @@ public class ConversationActivity extends BriarActivity
super.onCreate(state); super.onCreate(state);
Intent i = getIntent(); Intent i = getIntent();
byte[] b = i.getByteArrayExtra("briar.GROUP_ID"); int id = i.getIntExtra(CONTACT_ID, -1);
if (b == null) throw new IllegalStateException(); if (id == -1) throw new IllegalStateException();
groupId = new GroupId(b); contactId = new ContactId(id);
setContentView(R.layout.activity_conversation); setContentView(R.layout.activity_conversation);
@@ -185,9 +190,10 @@ public class ConversationActivity extends BriarActivity
ab.setDisplayShowTitleEnabled(false); ab.setDisplayShowTitleEnabled(false);
} }
String hexGroupId = StringUtils.toHexString(b); ViewCompat.setTransitionName(toolbarAvatar,
ViewCompat.setTransitionName(toolbarAvatar, "avatar" + hexGroupId); AndroidUtils.getAvatarTransitionName(contactId));
ViewCompat.setTransitionName(toolbarStatus, "bulb" + hexGroupId); ViewCompat.setTransitionName(toolbarStatus,
AndroidUtils.getBulbTransitionName(contactId));
adapter = new ConversationAdapter(this, this); adapter = new ConversationAdapter(this, this);
list = (BriarRecyclerView) findViewById(R.id.conversationView); list = (BriarRecyclerView) findViewById(R.id.conversationView);
@@ -220,8 +226,8 @@ public class ConversationActivity extends BriarActivity
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
eventBus.addListener(this); eventBus.addListener(this);
notificationManager.blockNotification(groupId); notificationManager.blockContactNotification(contactId);
notificationManager.clearPrivateMessageNotification(groupId); notificationManager.clearContactNotification(contactId);
loadContactDetails(); loadContactDetails();
loadMessages(); loadMessages();
list.startPeriodicUpdate(); list.startPeriodicUpdate();
@@ -231,7 +237,7 @@ public class ConversationActivity extends BriarActivity
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
eventBus.removeListener(this); eventBus.removeListener(this);
notificationManager.unblockNotification(groupId); notificationManager.unblockContactNotification(contactId);
list.stopPeriodicUpdate(); list.stopPeriodicUpdate();
if (isFinishing()) markMessagesRead(); if (isFinishing()) markMessagesRead();
} }
@@ -287,13 +293,10 @@ public class ConversationActivity extends BriarActivity
public void run() { public void run() {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (contactId == null) if (contactName == null || contactAuthorId == null) {
contactId = messagingManager.getContactId(groupId);
if (contactName == null || contactIdenticonKey == null) {
Contact contact = contactManager.getContact(contactId); Contact contact = contactManager.getContact(contactId);
contactName = contact.getAuthor().getName(); contactName = contact.getAuthor().getName();
contactIdenticonKey = contactAuthorId = contact.getAuthor().getId();
contact.getAuthor().getId().getBytes();
} }
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
@@ -314,7 +317,7 @@ public class ConversationActivity extends BriarActivity
@Override @Override
public void run() { public void run() {
toolbarAvatar.setImageDrawable( toolbarAvatar.setImageDrawable(
new IdenticonDrawable(contactIdenticonKey)); new IdenticonDrawable(contactAuthorId.getBytes()));
toolbarTitle.setText(contactName); toolbarTitle.setText(contactName);
if (connectionRegistry.isConnected(contactId)) { if (connectionRegistry.isConnected(contactId)) {
@@ -341,8 +344,6 @@ public class ConversationActivity extends BriarActivity
public void run() { public void run() {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (contactId == null)
contactId = messagingManager.getContactId(groupId);
Collection<PrivateMessageHeader> headers = Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(contactId); messagingManager.getMessageHeaders(contactId);
Collection<IntroductionMessage> introductions = Collection<IntroductionMessage> introductions =
@@ -419,12 +420,10 @@ public class ConversationActivity extends BriarActivity
ConversationItem item; ConversationItem item;
if (m instanceof IntroductionRequest) { if (m instanceof IntroductionRequest) {
IntroductionRequest i = (IntroductionRequest) m; IntroductionRequest i = (IntroductionRequest) m;
item = ConversationItem item = ConversationItem.from(this, contactName, i);
.from(ConversationActivity.this, contactName, i);
} else { } else {
IntroductionResponse i = (IntroductionResponse) m; IntroductionResponse i = (IntroductionResponse) m;
item = ConversationItem item = ConversationItem.from(this, contactName, i);
.from(ConversationActivity.this, contactName, i);
} }
items.add(item); items.add(item);
} }
@@ -432,12 +431,10 @@ public class ConversationActivity extends BriarActivity
ConversationItem item; ConversationItem item;
if (i instanceof InvitationRequest) { if (i instanceof InvitationRequest) {
InvitationRequest r = (InvitationRequest) i; InvitationRequest r = (InvitationRequest) i;
item = ConversationItem item = ConversationItem.from(this, contactName, r);
.from(ConversationActivity.this, contactName, r);
} else { } else {
InvitationResponse r = (InvitationResponse) i; InvitationResponse r = (InvitationResponse) i;
item = ConversationItem item = ConversationItem.from(this, contactName, r);
.from(ConversationActivity.this, contactName, r);
} }
items.add(item); items.add(item);
} }
@@ -540,7 +537,7 @@ public class ConversationActivity extends BriarActivity
} }
} else if (e instanceof PrivateMessageReceivedEvent) { } else if (e instanceof PrivateMessageReceivedEvent) {
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
if (p.getGroupId().equals(groupId)) { if (p.getContactId().equals(contactId)) {
LOG.info("Message received, adding"); LOG.info("Message received, adding");
PrivateMessageHeader h = p.getMessageHeader(); PrivateMessageHeader h = p.getMessageHeader();
addConversationItem(ConversationItem.from(h)); addConversationItem(ConversationItem.from(h));
@@ -640,7 +637,8 @@ public class ConversationActivity extends BriarActivity
text = StringUtils.truncateUtf8(text, MAX_PRIVATE_MESSAGE_BODY_LENGTH); text = StringUtils.truncateUtf8(text, MAX_PRIVATE_MESSAGE_BODY_LENGTH);
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
timestamp = Math.max(timestamp, getMinTimestampForNewMessage()); timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
createMessage(text, timestamp); if (messagingGroupId == null) loadGroupId(text, timestamp);
else createMessage(text, timestamp);
textInputView.setText(""); textInputView.setText("");
} }
@@ -650,13 +648,30 @@ public class ConversationActivity extends BriarActivity
return item == null ? 0 : item.getTime() + 1; return item == null ? 0 : item.getTime() + 1;
} }
private void loadGroupId(final String body, final long timestamp) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
messagingGroupId =
messagingManager.getConversationId(contactId);
createMessage(body, timestamp);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
private void createMessage(final String body, final long timestamp) { private void createMessage(final String body, final long timestamp) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
storeMessage(privateMessageFactory.createPrivateMessage( storeMessage(privateMessageFactory.createPrivateMessage(
groupId, timestamp, body), body); messagingGroupId, timestamp, body), body);
} catch (FormatException e) { } catch (FormatException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -674,14 +689,13 @@ public class ConversationActivity extends BriarActivity
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms"); LOG.info("Storing message took " + duration + " ms");
MessageId id = m.getMessage().getId(); Message message = m.getMessage();
PrivateMessageHeader h = PrivateMessageHeader h = new PrivateMessageHeader(
new PrivateMessageHeader(id, groupId, message.getId(), message.getGroupId(),
m.getMessage().getTimestamp(), true, false, message.getTimestamp(), true, false, false, false);
false, false);
ConversationItem item = ConversationItem.from(h); ConversationItem item = ConversationItem.from(h);
item.setBody(body); item.setBody(body);
bodyCache.put(id, body); bodyCache.put(message.getId(), body);
addConversationItem(item); addConversationItem(item);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
@@ -714,10 +728,6 @@ public class ConversationActivity extends BriarActivity
@Override @Override
public void run() { public void run() {
try { try {
// make sure contactId is initialised
if (contactId == null)
contactId = messagingManager.getContactId(groupId);
// remove contact with that ID
contactManager.removeContact(contactId); contactManager.removeContact(contactId);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
@@ -847,7 +857,7 @@ public class ConversationActivity extends BriarActivity
switch (item.getRequestType()) { switch (item.getRequestType()) {
case INTRODUCTION: case INTRODUCTION:
respondToIntroductionRequest(item.getSessionId(), respondToIntroductionRequest(item.getSessionId(),
accept, timestamp); accept, timestamp);
break; break;
case FORUM: case FORUM:
respondToForumRequest(item.getSessionId(), accept); respondToForumRequest(item.getSessionId(), accept);

View File

@@ -23,7 +23,6 @@ import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.messaging.ConversationManager; import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.sync.GroupId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -132,14 +131,12 @@ public class ContactChooserFragment extends BaseFragment {
c1 = c; c1 = c;
} else { } else {
ContactId id = c.getId(); ContactId id = c.getId();
GroupId groupId =
conversationManager.getConversationId(id);
GroupCount count = GroupCount count =
conversationManager.getGroupCount(id); conversationManager.getGroupCount(id);
boolean connected = boolean connected =
connectionRegistry.isConnected(c.getId()); connectionRegistry.isConnected(c.getId());
contacts.add(new ContactListItem(c, connected, contacts.add(new ContactListItem(c, connected,
groupId, count)); count));
} }
} }
displayContacts(contacts); displayContacts(contacts);

View File

@@ -7,9 +7,7 @@ import org.briarproject.R;
import org.briarproject.android.controller.handler.UiResultExceptionHandler; import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener; import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
import org.briarproject.android.sharing.ContactSelectorActivity; import org.briarproject.android.sharing.ContactSelectorActivity;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseExecutor;
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.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -7,10 +7,7 @@ import android.support.annotation.UiThread;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.BriarActivity; import org.briarproject.android.BriarActivity;
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener; import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import java.util.ArrayList; import java.util.ArrayList;
@@ -58,10 +55,6 @@ public abstract class ContactSelectorActivity extends BriarActivity implements
this.contacts = contacts; this.contacts = contacts;
} }
@DatabaseExecutor
public abstract boolean isDisabled(GroupId groupId, Contact c)
throws DbException;
static ArrayList<Integer> getContactsFromIds( static ArrayList<Integer> getContactsFromIds(
Collection<ContactId> contacts) { Collection<ContactId> contacts) {
// transform ContactIds to Integers so they can be added to a bundle // transform ContactIds to Integers so they can be added to a bundle

View File

@@ -11,7 +11,7 @@ import org.briarproject.api.sync.GroupId;
import java.util.Collection; import java.util.Collection;
public interface ContactSelectorListener extends DestroyableContext { interface ContactSelectorListener extends DestroyableContext {
@Deprecated @Deprecated
void runOnDbThread(Runnable runnable); void runOnDbThread(Runnable runnable);

View File

@@ -8,26 +8,26 @@ import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe @NotThreadSafe
@NotNullByDefault @NotNullByDefault
public class SelectableContactItem extends ContactItem { class SelectableContactItem extends ContactItem {
private boolean selected, disabled; private boolean selected, disabled;
public SelectableContactItem(Contact contact, boolean connected, SelectableContactItem(Contact contact, boolean connected,
boolean selected, boolean disabled) { boolean selected, boolean disabled) {
super(contact, connected); super(contact, connected);
this.selected = selected; this.selected = selected;
this.disabled = disabled; this.disabled = disabled;
} }
public boolean isSelected() { boolean isSelected() {
return selected; return selected;
} }
public void toggleSelected() { void toggleSelected() {
selected = !selected; selected = !selected;
} }
public boolean isDisabled() { boolean isDisabled() {
return disabled; return disabled;
} }

View File

@@ -23,6 +23,7 @@ import android.widget.TextView;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.view.ArticleMovementMethod; import org.briarproject.android.view.ArticleMovementMethod;
import org.briarproject.android.widget.LinkDialogFragment; import org.briarproject.android.widget.LinkDialogFragment;
import org.briarproject.api.contact.ContactId;
import org.briarproject.util.IoUtils; import org.briarproject.util.IoUtils;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
@@ -173,4 +174,11 @@ public class AndroidUtils {
v.setMovementMethod(ArticleMovementMethod.getInstance()); v.setMovementMethod(ArticleMovementMethod.getInstance());
} }
public static String getAvatarTransitionName(ContactId c) {
return "avatar" + c.getInt();
}
public static String getBulbTransitionName(ContactId c) {
return "bulb" + c.getInt();
}
} }

View File

@@ -4,7 +4,6 @@ import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.GroupId;
public interface ConversationManager { public interface ConversationManager {
@@ -14,9 +13,6 @@ public interface ConversationManager {
*/ */
void registerConversationClient(ConversationClient client); void registerConversationClient(ConversationClient client);
/** Get the main group ID that represents this conversation */
GroupId getConversationId(ContactId contactId) throws DbException;
/** Get the unified group count for all private conversation messages. */ /** Get the unified group count for all private conversation messages. */
GroupCount getGroupCount(ContactId contactId) throws DbException; GroupCount getGroupCount(ContactId contactId) throws DbException;

View File

@@ -1,15 +1,11 @@
package org.briarproject.messaging; package org.briarproject.messaging;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker.GroupCount; import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.messaging.ConversationManager; import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
@@ -19,14 +15,11 @@ import javax.inject.Inject;
class ConversationManagerImpl implements ConversationManager { class ConversationManagerImpl implements ConversationManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final ContactGroupFactory contactGroupFactory;
private final Set<ConversationClient> clients; private final Set<ConversationClient> clients;
@Inject @Inject
ConversationManagerImpl(DatabaseComponent db, ConversationManagerImpl(DatabaseComponent db) {
ContactGroupFactory contactGroupFactory) {
this.db = db; this.db = db;
this.contactGroupFactory = contactGroupFactory;
clients = new CopyOnWriteArraySet<ConversationClient>(); clients = new CopyOnWriteArraySet<ConversationClient>();
} }
@@ -38,23 +31,6 @@ class ConversationManagerImpl implements ConversationManager {
} }
} }
@Override
public GroupId getConversationId(ContactId contactId) throws DbException {
// TODO we should probably transition this to its own group
// and/or work with the ContactId in the UI instead
Contact contact;
Transaction txn = db.startTransaction(true);
try {
contact = db.getContact(txn, contactId);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
Group group = contactGroupFactory
.createContactGroup(MessagingManagerImpl.CLIENT_ID, contact);
return group.getId();
}
@Override @Override
public GroupCount getGroupCount(ContactId contactId) public GroupCount getGroupCount(ContactId contactId)
throws DbException { throws DbException {