Refactor UI event listeners.

This commit is contained in:
akwizgran
2018-11-07 17:45:21 +00:00
parent b2702062bc
commit b8e390db21
27 changed files with 191 additions and 283 deletions

View File

@@ -104,9 +104,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private ContactId blockedContact = null; private ContactId blockedContact = null;
private GroupId blockedGroup = null; private GroupId blockedGroup = null;
private boolean blockSignInReminder = false; private boolean blockSignInReminder = false;
private boolean blockContacts = false, blockGroups = false; private boolean blockBlogs = false;
private boolean blockForums = false, blockBlogs = false;
private boolean blockIntroductions = false;
private long lastSound = 0; private long lastSound = 0;
private volatile Settings settings = new Settings(); private volatile Settings settings = new Settings();
@@ -237,7 +235,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} }
} }
@UiThread @UiThread
@Override @Override
public Notification getForegroundNotification() { public Notification getForegroundNotification() {
@@ -278,13 +275,11 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
notificationManager.notify(ONGOING_NOTIFICATION_ID, n); notificationManager.notify(ONGOING_NOTIFICATION_ID, n);
} }
@UiThread
private void showContactNotification(ContactId c) { private void showContactNotification(ContactId c) {
androidExecutor.runOnUiThread(() -> { if (c.equals(blockedContact)) return;
if (blockContacts) return; contactCounts.add(c);
if (c.equals(blockedContact)) return; updateContactNotification(true);
contactCounts.add(c);
updateContactNotification(true);
});
} }
@Override @Override
@@ -381,12 +376,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@UiThread @UiThread
private void showGroupMessageNotification(GroupId g) { private void showGroupMessageNotification(GroupId g) {
androidExecutor.runOnUiThread(() -> { if (g.equals(blockedGroup)) return;
if (blockGroups) return; groupCounts.add(g);
if (g.equals(blockedGroup)) return; updateGroupMessageNotification(true);
groupCounts.add(g);
updateGroupMessageNotification(true);
});
} }
@Override @Override
@@ -452,12 +444,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@UiThread @UiThread
private void showForumPostNotification(GroupId g) { private void showForumPostNotification(GroupId g) {
androidExecutor.runOnUiThread(() -> { if (g.equals(blockedGroup)) return;
if (blockForums) return; forumCounts.add(g);
if (g.equals(blockedGroup)) return; updateForumPostNotification(true);
forumCounts.add(g);
updateForumPostNotification(true);
});
} }
@Override @Override
@@ -522,12 +511,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@UiThread @UiThread
private void showBlogPostNotification(GroupId g) { private void showBlogPostNotification(GroupId g) {
androidExecutor.runOnUiThread(() -> { if (blockBlogs) return;
if (blockBlogs) return; if (g.equals(blockedGroup)) return;
if (g.equals(blockedGroup)) return; blogCounts.add(g);
blogCounts.add(g); updateBlogPostNotification(true);
updateBlogPostNotification(true);
});
} }
@Override @Override
@@ -575,12 +562,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
(Runnable) this::clearBlogPostNotification); (Runnable) this::clearBlogPostNotification);
} }
@UiThread
private void showIntroductionNotification() { private void showIntroductionNotification() {
androidExecutor.runOnUiThread(() -> { introductionTotal++;
if (blockIntroductions) return; updateIntroductionNotification();
introductionTotal++;
updateIntroductionNotification();
});
} }
@UiThread @UiThread

View File

@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.android.DestroyableContext;
import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.android.controller.handler.ExceptionHandler;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
import org.briarproject.briar.api.blog.BlogPostHeader; import org.briarproject.briar.api.blog.BlogPostHeader;
@@ -36,10 +35,11 @@ interface BaseController {
void repeatPost(BlogPostItem item, @Nullable String comment, void repeatPost(BlogPostItem item, @Nullable String comment,
ExceptionHandler<DbException> handler); ExceptionHandler<DbException> handler);
@UiThread
void setBlogListener(BlogListener listener); void setBlogListener(BlogListener listener);
@NotNullByDefault @NotNullByDefault
interface BlogListener extends DestroyableContext { interface BlogListener {
@UiThread @UiThread
void onBlogPostAdded(BlogPostHeader header, boolean local); void onBlogPostAdded(BlogPostHeader header, boolean local);

View File

@@ -86,15 +86,6 @@ abstract class BaseControllerImpl extends DbControllerImpl
this.listener = listener; this.listener = listener;
} }
void onBlogPostAdded(BlogPostHeader h, boolean local) {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onBlogPostAdded(h, local));
}
void onBlogRemoved() {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogRemoved());
}
@Override @Override
public void loadBlogPosts(GroupId groupId, public void loadBlogPosts(GroupId groupId,
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {

View File

@@ -16,6 +16,7 @@ public interface BlogController extends BaseController {
void setGroupId(GroupId g); void setGroupId(GroupId g);
@UiThread
void setBlogSharingListener(BlogSharingListener listener); void setBlogSharingListener(BlogSharingListener listener);
void loadBlogPosts( void loadBlogPosts(

View File

@@ -49,8 +49,11 @@ class BlogControllerImpl extends BaseControllerImpl
Logger.getLogger(BlogControllerImpl.class.getName()); Logger.getLogger(BlogControllerImpl.class.getName());
private final BlogSharingManager blogSharingManager; private final BlogSharingManager blogSharingManager;
// UI thread
private BlogSharingListener listener;
private volatile GroupId groupId = null; private volatile GroupId groupId = null;
private volatile BlogSharingListener listener;
@Inject @Inject
BlogControllerImpl(@DatabaseExecutor Executor dbExecutor, BlogControllerImpl(@DatabaseExecutor Executor dbExecutor,
@@ -102,7 +105,7 @@ class BlogControllerImpl extends BaseControllerImpl
BlogPostAddedEvent b = (BlogPostAddedEvent) e; BlogPostAddedEvent b = (BlogPostAddedEvent) e;
if (b.getGroupId().equals(groupId)) { if (b.getGroupId().equals(groupId)) {
LOG.info("Blog post added"); LOG.info("Blog post added");
onBlogPostAdded(b.getHeader(), b.isLocal()); listener.onBlogPostAdded(b.getHeader(), b.isLocal());
} }
} else if (e instanceof BlogInvitationResponseReceivedEvent) { } else if (e instanceof BlogInvitationResponseReceivedEvent) {
BlogInvitationResponseReceivedEvent b = BlogInvitationResponseReceivedEvent b =
@@ -110,32 +113,23 @@ class BlogControllerImpl extends BaseControllerImpl
BlogInvitationResponse r = b.getMessageHeader(); BlogInvitationResponse r = b.getMessageHeader();
if (r.getShareableId().equals(groupId) && r.wasAccepted()) { if (r.getShareableId().equals(groupId) && r.wasAccepted()) {
LOG.info("Blog invitation accepted"); LOG.info("Blog invitation accepted");
onBlogInvitationAccepted(b.getContactId()); listener.onBlogInvitationAccepted(b.getContactId());
} }
} else if (e instanceof ContactLeftShareableEvent) { } else if (e instanceof ContactLeftShareableEvent) {
ContactLeftShareableEvent s = (ContactLeftShareableEvent) e; ContactLeftShareableEvent s = (ContactLeftShareableEvent) e;
if (s.getGroupId().equals(groupId)) { if (s.getGroupId().equals(groupId)) {
LOG.info("Blog left by contact"); LOG.info("Blog left by contact");
onBlogLeft(s.getContactId()); listener.onBlogLeft(s.getContactId());
} }
} else if (e instanceof GroupRemovedEvent) { } else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e; GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getId().equals(groupId)) { if (g.getGroup().getId().equals(groupId)) {
LOG.info("Blog removed"); LOG.info("Blog removed");
onBlogRemoved(); listener.onBlogRemoved();
} }
} }
} }
private void onBlogInvitationAccepted(ContactId c) {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onBlogInvitationAccepted(c));
}
private void onBlogLeft(ContactId c) {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogLeft(c));
}
@Override @Override
public void loadBlogPosts( public void loadBlogPosts(
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {

View File

@@ -17,6 +17,7 @@ public interface FeedController extends BaseController {
void loadPersonalBlog(ResultExceptionHandler<Blog, DbException> handler); void loadPersonalBlog(ResultExceptionHandler<Blog, DbException> handler);
@UiThread
void setFeedListener(FeedListener listener); void setFeedListener(FeedListener listener);
@NotNullByDefault @NotNullByDefault

View File

@@ -34,13 +34,13 @@ import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class FeedControllerImpl extends BaseControllerImpl class FeedControllerImpl extends BaseControllerImpl implements FeedController {
implements FeedController {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(FeedControllerImpl.class.getName()); Logger.getLogger(FeedControllerImpl.class.getName());
private volatile FeedListener listener; // UI thread
private FeedListener listener;
@Inject @Inject
FeedControllerImpl(@DatabaseExecutor Executor dbExecutor, FeedControllerImpl(@DatabaseExecutor Executor dbExecutor,
@@ -76,26 +76,22 @@ class FeedControllerImpl extends BaseControllerImpl
if (e instanceof BlogPostAddedEvent) { if (e instanceof BlogPostAddedEvent) {
BlogPostAddedEvent b = (BlogPostAddedEvent) e; BlogPostAddedEvent b = (BlogPostAddedEvent) e;
LOG.info("Blog post added"); LOG.info("Blog post added");
onBlogPostAdded(b.getHeader(), b.isLocal()); listener.onBlogPostAdded(b.getHeader(), b.isLocal());
} else if (e instanceof GroupAddedEvent) { } else if (e instanceof GroupAddedEvent) {
GroupAddedEvent g = (GroupAddedEvent) e; GroupAddedEvent g = (GroupAddedEvent) e;
if (g.getGroup().getClientId().equals(CLIENT_ID)) { if (g.getGroup().getClientId().equals(CLIENT_ID)) {
LOG.info("Blog added"); LOG.info("Blog added");
onBlogAdded(); listener.onBlogAdded();
} }
} else if (e instanceof GroupRemovedEvent) { } else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e; GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getClientId().equals(CLIENT_ID)) { if (g.getGroup().getClientId().equals(CLIENT_ID)) {
LOG.info("Blog removed"); LOG.info("Blog removed");
onBlogRemoved(); listener.onBlogRemoved();
} }
} }
} }
private void onBlogAdded() {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogAdded());
}
@Override @Override
public void loadBlogPosts( public void loadBlogPosts(
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.contact;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.UiThread;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
@@ -253,37 +254,34 @@ public class ContactListFragment extends BaseFragment implements EventListener {
} }
} }
@UiThread
private void updateItem(ContactId c, ConversationMessageHeader h) { private void updateItem(ContactId c, ConversationMessageHeader h) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); int position = adapter.findItemPosition(c);
int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItemAt(position);
ContactListItem item = adapter.getItemAt(position); if (item != null) {
if (item != null) { item.addMessage(h);
item.addMessage(h); adapter.updateItemAt(position, item);
adapter.updateItemAt(position, item); }
}
});
} }
@UiThread
private void removeItem(ContactId c) { private void removeItem(ContactId c) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); int position = adapter.findItemPosition(c);
int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItemAt(position);
ContactListItem item = adapter.getItemAt(position); if (item != null) adapter.remove(item);
if (item != null) adapter.remove(item);
});
} }
@UiThread
private void setConnected(ContactId c, boolean connected) { private void setConnected(ContactId c, boolean connected) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); int position = adapter.findItemPosition(c);
int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItemAt(position);
ContactListItem item = adapter.getItemAt(position); if (item != null) {
if (item != null) { item.setConnected(connected);
item.setConnected(connected); adapter.updateItemAt(position, item);
adapter.updateItemAt(position, item); }
}
});
} }
} }

View File

@@ -4,12 +4,11 @@ import android.support.annotation.UiThread;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.android.DestroyableContext;
import java.util.Collection; import java.util.Collection;
@NotNullByDefault @NotNullByDefault
public interface ContactSelectorListener extends DestroyableContext { public interface ContactSelectorListener {
@UiThread @UiThread
void contactsSelected(Collection<ContactId> contacts); void contactsSelected(Collection<ContactId> contacts);

View File

@@ -4,7 +4,6 @@ import android.support.annotation.UiThread;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.android.DestroyableContext;
import java.util.Collection; import java.util.Collection;
@@ -62,7 +61,8 @@ public interface SharingController {
@UiThread @UiThread
int getTotalCount(); int getTotalCount();
interface SharingListener extends DestroyableContext { interface SharingListener {
@UiThread @UiThread
void onSharingInfoUpdated(int total, int online); void onSharingInfoUpdated(int total, int online);
} }

View File

@@ -1,5 +1,7 @@
package org.briarproject.briar.android.controller; package org.briarproject.briar.android.controller;
import android.support.annotation.UiThread;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
@@ -22,11 +24,13 @@ public class SharingControllerImpl implements SharingController, EventListener {
private final EventBus eventBus; private final EventBus eventBus;
private final ConnectionRegistry connectionRegistry; private final ConnectionRegistry connectionRegistry;
@Nullable // UI thread
private volatile SharingListener listener;
// only access on @UiThread
private final Set<ContactId> contacts = new HashSet<>(); private final Set<ContactId> contacts = new HashSet<>();
// UI thread
@Nullable
private SharingListener listener;
@Inject @Inject
SharingControllerImpl(EventBus eventBus, SharingControllerImpl(EventBus eventBus,
ConnectionRegistry connectionRegistry) { ConnectionRegistry connectionRegistry) {
@@ -58,14 +62,13 @@ public class SharingControllerImpl implements SharingController, EventListener {
} }
} }
@UiThread
private void setConnected(ContactId c) { private void setConnected(ContactId c) {
if (listener == null) return; if (listener == null) throw new IllegalStateException();
listener.runOnUiThreadUnlessDestroyed(() -> { if (contacts.contains(c)) {
if (contacts.contains(c)) { int online = getOnlineCount();
int online = getOnlineCount(); listener.onSharingInfoUpdated(contacts.size(), online);
listener.onSharingInfoUpdated(contacts.size(), online); }
}
});
} }
@Override @Override

View File

@@ -398,22 +398,17 @@ public class ConversationActivity extends BriarActivity
} }
} }
@UiThread
private void displayContactOnlineStatus() { private void displayContactOnlineStatus() {
runOnUiThreadUnlessDestroyed(() -> { if (connectionRegistry.isConnected(contactId)) {
if (connectionRegistry.isConnected(contactId)) { toolbarStatus.setImageDrawable(ContextCompat.getDrawable(
toolbarStatus.setImageDrawable(ContextCompat ConversationActivity.this, R.drawable.contact_online));
.getDrawable(ConversationActivity.this, toolbarStatus.setContentDescription(getString(R.string.online));
R.drawable.contact_online)); } else {
toolbarStatus toolbarStatus.setImageDrawable(ContextCompat.getDrawable(
.setContentDescription(getString(R.string.online)); ConversationActivity.this, R.drawable.contact_offline));
} else { toolbarStatus.setContentDescription(getString(R.string.offline));
toolbarStatus.setImageDrawable(ContextCompat }
.getDrawable(ConversationActivity.this,
R.drawable.contact_offline));
toolbarStatus
.setContentDescription(getString(R.string.offline));
}
});
} }
private void loadMessages() { private void loadMessages() {
@@ -583,7 +578,7 @@ public class ConversationActivity extends BriarActivity
ContactRemovedEvent c = (ContactRemovedEvent) e; ContactRemovedEvent c = (ContactRemovedEvent) e;
if (c.getContactId().equals(contactId)) { if (c.getContactId().equals(contactId)) {
LOG.info("Contact removed"); LOG.info("Contact removed");
finishOnUiThread(); supportFinishAfterTransition();
} }
} else if (e instanceof ConversationMessageReceivedEvent) { } else if (e instanceof ConversationMessageReceivedEvent) {
ConversationMessageReceivedEvent p = ConversationMessageReceivedEvent p =
@@ -619,47 +614,43 @@ public class ConversationActivity extends BriarActivity
} }
} }
@UiThread
private void addConversationItem(ConversationItem item) { private void addConversationItem(ConversationItem item) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); adapter.add(item);
adapter.add(item); // When adding a new message, scroll to the bottom if the conversation
// When adding a new message, scroll to the bottom if the // is visible, even if we're not currently at the bottom
// conversation is visible, even if we're not currently at if (getLifecycle().getCurrentState().isAtLeast(STARTED))
// the bottom scrollToBottom();
if (getLifecycle().getCurrentState().isAtLeast(STARTED))
scrollToBottom();
});
} }
@UiThread
private void onNewConversationMessage(ConversationMessageHeader h) { private void onNewConversationMessage(ConversationMessageHeader h) {
runOnUiThreadUnlessDestroyed(() -> { if (h instanceof ConversationRequest ||
if (h instanceof ConversationRequest || h instanceof ConversationResponse) {
h instanceof ConversationResponse) { // contact name might not have been loaded
// contact name might not have been loaded observeOnce(viewModel.getContactDisplayName(), this,
observeOnce(viewModel.getContactDisplayName(), this, name -> addConversationItem(h.accept(visitor)));
name -> addConversationItem(h.accept(visitor))); } else {
} else { // visitor also loads message text (if existing)
// visitor also loads message text (if existing) addConversationItem(h.accept(visitor));
addConversationItem(h.accept(visitor)); }
}
});
} }
@UiThread
private void markMessages(Collection<MessageId> messageIds, boolean sent, private void markMessages(Collection<MessageId> messageIds, boolean sent,
boolean seen) { boolean seen) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); Set<MessageId> messages = new HashSet<>(messageIds);
Set<MessageId> messages = new HashSet<>(messageIds); SparseArray<ConversationItem> list = adapter.getOutgoingMessages();
SparseArray<ConversationItem> list = adapter.getOutgoingMessages(); for (int i = 0; i < list.size(); i++) {
for (int i = 0; i < list.size(); i++) { ConversationItem item = list.valueAt(i);
ConversationItem item = list.valueAt(i); if (messages.contains(item.getId())) {
if (messages.contains(item.getId())) { item.setSent(sent);
item.setSent(sent); item.setSeen(seen);
item.setSeen(seen); adapter.notifyItemChanged(list.keyAt(i));
adapter.notifyItemChanged(list.keyAt(i));
}
} }
}); }
} }
@Override @Override

View File

@@ -79,7 +79,7 @@ class ForumControllerImpl extends
ForumPostReceivedEvent f = (ForumPostReceivedEvent) e; ForumPostReceivedEvent f = (ForumPostReceivedEvent) e;
if (f.getGroupId().equals(getGroupId())) { if (f.getGroupId().equals(getGroupId())) {
LOG.info("Forum post received, adding..."); LOG.info("Forum post received, adding...");
onForumPostReceived(f.getHeader(), f.getText()); listener.onItemReceived(buildItem(f.getHeader(), f.getText()));
} }
} else if (e instanceof ForumInvitationResponseReceivedEvent) { } else if (e instanceof ForumInvitationResponseReceivedEvent) {
ForumInvitationResponseReceivedEvent f = ForumInvitationResponseReceivedEvent f =
@@ -87,13 +87,13 @@ class ForumControllerImpl extends
ForumInvitationResponse r = f.getMessageHeader(); ForumInvitationResponse r = f.getMessageHeader();
if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) { if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) {
LOG.info("Forum invitation was accepted"); LOG.info("Forum invitation was accepted");
onForumInvitationAccepted(f.getContactId()); listener.onInvitationAccepted(f.getContactId());
} }
} else if (e instanceof ContactLeftShareableEvent) { } else if (e instanceof ContactLeftShareableEvent) {
ContactLeftShareableEvent c = (ContactLeftShareableEvent) e; ContactLeftShareableEvent c = (ContactLeftShareableEvent) e;
if (c.getGroupId().equals(getGroupId())) { if (c.getGroupId().equals(getGroupId())) {
LOG.info("Forum left by contact"); LOG.info("Forum left by contact");
onForumLeft(c.getContactId()); listener.onForumLeft(c.getContactId());
} }
} }
} }
@@ -168,8 +168,7 @@ class ForumControllerImpl extends
} }
@Override @Override
protected ForumPostHeader addLocalMessage(ForumPost p) protected ForumPostHeader addLocalMessage(ForumPost p) throws DbException {
throws DbException {
return forumManager.addLocalPost(p); return forumManager.addLocalPost(p);
} }
@@ -183,19 +182,4 @@ class ForumControllerImpl extends
return new ForumItem(header, text); return new ForumItem(header, text);
} }
private void onForumPostReceived(ForumPostHeader h, String text) {
ForumItem item = buildItem(h, text);
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onItemReceived(item));
}
private void onForumInvitationAccepted(ContactId c) {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onInvitationAccepted(c));
}
private void onForumLeft(ContactId c) {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onForumLeft(c));
}
} }

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.forum;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.UiThread;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
@@ -244,25 +245,23 @@ public class ForumListFragment extends BaseEventFragment implements
} }
} }
@UiThread
private void updateItem(GroupId g, ForumPostHeader m) { private void updateItem(GroupId g, ForumPostHeader m) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); int position = adapter.findItemPosition(g);
int position = adapter.findItemPosition(g); ForumListItem item = adapter.getItemAt(position);
ForumListItem item = adapter.getItemAt(position); if (item != null) {
if (item != null) { item.addHeader(m);
item.addHeader(m); adapter.updateItemAt(position, item);
adapter.updateItemAt(position, item); }
}
});
} }
@UiThread
private void removeForum(GroupId g) { private void removeForum(GroupId g) {
runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision();
adapter.incrementRevision(); int position = adapter.findItemPosition(g);
int position = adapter.findItemPosition(g); ForumListItem item = adapter.getItemAt(position);
ForumListItem item = adapter.getItemAt(position); if (item != null) adapter.remove(item);
if (item != null) adapter.remove(item);
});
} }
@Override @Override

View File

@@ -285,38 +285,32 @@ public class KeyAgreementFragment extends BaseEventFragment
} }
} }
@UiThread
private void keyAgreementFailed() { private void keyAgreementFailed() {
runOnUiThreadUnlessDestroyed(() -> { reset();
reset(); listener.keyAgreementFailed();
listener.keyAgreementFailed();
});
} }
@UiThread
private void keyAgreementWaiting() { private void keyAgreementWaiting() {
runOnUiThreadUnlessDestroyed( status.setText(listener.keyAgreementWaiting());
() -> status.setText(listener.keyAgreementWaiting()));
} }
@UiThread
private void keyAgreementStarted() { private void keyAgreementStarted() {
runOnUiThreadUnlessDestroyed(() -> { qrCodeView.setVisibility(INVISIBLE);
qrCodeView.setVisibility(INVISIBLE); statusView.setVisibility(VISIBLE);
statusView.setVisibility(VISIBLE); status.setText(listener.keyAgreementStarted());
status.setText(listener.keyAgreementStarted());
});
} }
private void keyAgreementAborted(boolean remoteAborted) { private void keyAgreementAborted(boolean remoteAborted) {
runOnUiThreadUnlessDestroyed(() -> { reset();
reset(); listener.keyAgreementAborted(remoteAborted);
listener.keyAgreementAborted(remoteAborted);
});
} }
private void keyAgreementFinished(KeyAgreementResult result) { private void keyAgreementFinished(KeyAgreementResult result) {
runOnUiThreadUnlessDestroyed(() -> { statusView.setVisibility(VISIBLE);
statusView.setVisibility(VISIBLE); status.setText(listener.keyAgreementFinished(result));
status.setText(listener.keyAgreementFinished(result));
});
} }
private void setQrCode(Payload localPayload) { private void setQrCode(Payload localPayload) {

View File

@@ -73,12 +73,9 @@ public class OpenDatabaseActivity extends BriarActivity
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof LifecycleEvent) { if (e instanceof LifecycleEvent) {
LifecycleState state = ((LifecycleEvent) e).getLifecycleState(); LifecycleState state = ((LifecycleEvent) e).getLifecycleState();
if (state.isAfter(STARTING_SERVICES)) if (state.isAfter(STARTING_SERVICES)) finishAndStartApp();
runOnUiThreadUnlessDestroyed(this::finishAndStartApp); else if (state == MIGRATING_DATABASE) showMigration();
else if (state == MIGRATING_DATABASE) else if (state == COMPACTING_DATABASE) showCompaction();
runOnUiThreadUnlessDestroyed(this::showMigration);
else if (state == COMPACTING_DATABASE)
runOnUiThreadUnlessDestroyed(this::showCompaction);
} }
} }

View File

@@ -6,6 +6,7 @@ import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.design.widget.NavigationView.OnNavigationItemSelectedListener; import android.support.design.widget.NavigationView.OnNavigationItemSelectedListener;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
@@ -435,17 +436,16 @@ public class NavDrawerActivity extends BriarActivity implements
}; };
} }
@UiThread
private void setTransport(TransportId id, boolean enabled) { private void setTransport(TransportId id, boolean enabled) {
runOnUiThreadUnlessDestroyed(() -> { if (transports == null || transportsAdapter == null) return;
if (transports == null || transportsAdapter == null) return; for (Transport t : transports) {
for (Transport t : transports) { if (t.id.equals(id)) {
if (t.id.equals(id)) { t.enabled = enabled;
t.enabled = enabled; transportsAdapter.notifyDataSetChanged();
transportsAdapter.notifyDataSetChanged(); break;
break;
}
} }
}); }
} }
private void updateTransports() { private void updateTransports() {

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.navdrawer;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.support.annotation.UiThread;
import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -53,7 +54,8 @@ public class NavDrawerControllerImpl extends DbControllerImpl
private final SettingsManager settingsManager; private final SettingsManager settingsManager;
private final EventBus eventBus; private final EventBus eventBus;
private volatile TransportStateListener listener; // UI thread
private TransportStateListener listener;
@Inject @Inject
NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor, NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor,
@@ -102,9 +104,9 @@ public class NavDrawerControllerImpl extends DbControllerImpl
} }
} }
@UiThread
private void transportStateUpdate(TransportId id, boolean enabled) { private void transportStateUpdate(TransportId id, boolean enabled) {
listener.runOnUiThreadUnlessDestroyed( listener.stateUpdate(id, enabled);
() -> listener.stateUpdate(id, enabled));
} }
@Override @Override

View File

@@ -1,9 +1,11 @@
package org.briarproject.briar.android.navdrawer; package org.briarproject.briar.android.navdrawer;
import android.support.annotation.UiThread;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.briar.android.DestroyableContext;
interface TransportStateListener extends DestroyableContext { interface TransportStateListener {
@UiThread
void stateUpdate(TransportId id, boolean enabled); void stateUpdate(TransportId id, boolean enabled);
} }

View File

@@ -84,31 +84,26 @@ class GroupControllerImpl extends
GroupMessageAddedEvent g = (GroupMessageAddedEvent) e; GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
if (!g.isLocal() && g.getGroupId().equals(getGroupId())) { if (!g.isLocal() && g.getGroupId().equals(getGroupId())) {
LOG.info("Group message received, adding..."); LOG.info("Group message received, adding...");
GroupMessageItem item = buildItem(g.getHeader(), g.getText()); listener.onItemReceived(buildItem(g.getHeader(), g.getText()));
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onItemReceived(item));
} }
} else if (e instanceof ContactRelationshipRevealedEvent) { } else if (e instanceof ContactRelationshipRevealedEvent) {
ContactRelationshipRevealedEvent c = ContactRelationshipRevealedEvent c =
(ContactRelationshipRevealedEvent) e; (ContactRelationshipRevealedEvent) e;
if (getGroupId().equals(c.getGroupId())) { if (getGroupId().equals(c.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onContactRelationshipRevealed(c.getMemberId(),
listener.onContactRelationshipRevealed(c.getMemberId(), c.getContactId(), c.getVisibility());
c.getContactId(), c.getVisibility()));
} }
} else if (e instanceof GroupInvitationResponseReceivedEvent) { } else if (e instanceof GroupInvitationResponseReceivedEvent) {
GroupInvitationResponseReceivedEvent g = GroupInvitationResponseReceivedEvent g =
(GroupInvitationResponseReceivedEvent) e; (GroupInvitationResponseReceivedEvent) e;
GroupInvitationResponse r = g.getMessageHeader(); GroupInvitationResponse r = g.getMessageHeader();
if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) { if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
listener.runOnUiThreadUnlessDestroyed( listener.onInvitationAccepted(g.getContactId());
() -> listener.onInvitationAccepted(g.getContactId()));
} }
} else if (e instanceof GroupDissolvedEvent) { } else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e; GroupDissolvedEvent g = (GroupDissolvedEvent) e;
if (getGroupId().equals(g.getGroupId())) { if (getGroupId().equals(g.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed( listener.onGroupDissolved();
() -> listener.onGroupDissolved());
} }
} }
} }

View File

@@ -5,7 +5,6 @@ import android.support.annotation.UiThread;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.android.DestroyableContext;
import org.briarproject.briar.android.controller.DbController; import org.briarproject.briar.android.controller.DbController;
import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.android.controller.handler.ExceptionHandler;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
@@ -19,6 +18,7 @@ interface GroupListController extends DbController {
/** /**
* The listener must be set right after the controller was injected * The listener must be set right after the controller was injected
*/ */
@UiThread
void setGroupListListener(GroupListListener listener); void setGroupListListener(GroupListListener listener);
@UiThread @UiThread
@@ -35,7 +35,7 @@ interface GroupListController extends DbController {
void loadAvailableGroups( void loadAvailableGroups(
ResultExceptionHandler<Integer, DbException> result); ResultExceptionHandler<Integer, DbException> result);
interface GroupListListener extends DestroyableContext { interface GroupListListener {
@UiThread @UiThread
void onGroupMessageAdded(GroupMessageHeader header); void onGroupMessageAdded(GroupMessageHeader header);

View File

@@ -23,7 +23,6 @@ import org.briarproject.briar.android.controller.handler.ExceptionHandler;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import org.briarproject.briar.api.privategroup.GroupMessageHeader;
import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupManager; import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.briarproject.briar.api.privategroup.event.GroupDissolvedEvent; import org.briarproject.briar.api.privategroup.event.GroupDissolvedEvent;
@@ -61,7 +60,8 @@ class GroupListControllerImpl extends DbControllerImpl
private final AndroidNotificationManager notificationManager; private final AndroidNotificationManager notificationManager;
private final EventBus eventBus; private final EventBus eventBus;
protected volatile GroupListListener listener; // UI thread
private GroupListListener listener;
@Inject @Inject
GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor, GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor,
@@ -85,9 +85,7 @@ class GroupListControllerImpl extends DbControllerImpl
@Override @Override
@CallSuper @CallSuper
public void onStart() { public void onStart() {
if (listener == null) if (listener == null) throw new IllegalStateException();
throw new IllegalStateException(
"GroupListListener needs to be attached");
eventBus.addListener(this); eventBus.addListener(this);
notificationManager.clearAllGroupMessageNotifications(); notificationManager.clearAllGroupMessageNotifications();
} }
@@ -104,54 +102,31 @@ class GroupListControllerImpl extends DbControllerImpl
if (e instanceof GroupMessageAddedEvent) { if (e instanceof GroupMessageAddedEvent) {
GroupMessageAddedEvent g = (GroupMessageAddedEvent) e; GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
LOG.info("Private group message added"); LOG.info("Private group message added");
onGroupMessageAdded(g.getHeader()); listener.onGroupMessageAdded(g.getHeader());
} else if (e instanceof GroupInvitationRequestReceivedEvent) { } else if (e instanceof GroupInvitationRequestReceivedEvent) {
LOG.info("Private group invitation received"); LOG.info("Private group invitation received");
onGroupInvitationReceived(); listener.onGroupInvitationReceived();
} else if (e instanceof GroupAddedEvent) { } else if (e instanceof GroupAddedEvent) {
GroupAddedEvent g = (GroupAddedEvent) e; GroupAddedEvent g = (GroupAddedEvent) e;
ClientId id = g.getGroup().getClientId(); ClientId id = g.getGroup().getClientId();
if (id.equals(CLIENT_ID)) { if (id.equals(CLIENT_ID)) {
LOG.info("Private group added"); LOG.info("Private group added");
onGroupAdded(g.getGroup().getId()); listener.onGroupAdded(g.getGroup().getId());
} }
} else if (e instanceof GroupRemovedEvent) { } else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e; GroupRemovedEvent g = (GroupRemovedEvent) e;
ClientId id = g.getGroup().getClientId(); ClientId id = g.getGroup().getClientId();
if (id.equals(CLIENT_ID)) { if (id.equals(CLIENT_ID)) {
LOG.info("Private group removed"); LOG.info("Private group removed");
onGroupRemoved(g.getGroup().getId()); listener.onGroupRemoved(g.getGroup().getId());
} }
} else if (e instanceof GroupDissolvedEvent) { } else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e; GroupDissolvedEvent g = (GroupDissolvedEvent) e;
LOG.info("Private group dissolved"); LOG.info("Private group dissolved");
onGroupDissolved(g.getGroupId()); listener.onGroupDissolved(g.getGroupId());
} }
} }
private void onGroupMessageAdded(GroupMessageHeader h) {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onGroupMessageAdded(h));
}
private void onGroupInvitationReceived() {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onGroupInvitationReceived());
}
private void onGroupAdded(GroupId g) {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupAdded(g));
}
private void onGroupRemoved(GroupId g) {
listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupRemoved(g));
}
private void onGroupDissolved(GroupId g) {
listener.runOnUiThreadUnlessDestroyed(
() -> listener.onGroupDissolved(g));
}
@Override @Override
public void loadGroups( public void loadGroups(
ResultExceptionHandler<Collection<GroupItem>, DbException> handler) { ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {

View File

@@ -95,8 +95,7 @@ public class GroupMemberListActivity extends BriarActivity
} else if (e instanceof GroupRemovedEvent) { } else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e; GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getId().equals(groupId)) { if (g.getGroup().getId().equals(groupId)) {
runOnUiThreadUnlessDestroyed( supportFinishAfterTransition();
this::supportFinishAfterTransition);
} }
} }
// TODO ContactConnectedEvent and ContactDisconnectedEvent // TODO ContactConnectedEvent and ContactDisconnectedEvent

View File

@@ -39,6 +39,8 @@ public abstract class InvitationControllerImpl<I extends InvitationItem>
Logger.getLogger(InvitationControllerImpl.class.getName()); Logger.getLogger(InvitationControllerImpl.class.getName());
private final EventBus eventBus; private final EventBus eventBus;
// UI thread
protected InvitationListener listener; protected InvitationListener listener;
public InvitationControllerImpl(@DatabaseExecutor Executor dbExecutor, public InvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,

View File

@@ -100,8 +100,7 @@ abstract class SharingStatusActivity extends BriarActivity
} else if (e instanceof GroupRemovedEvent) { } else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e; GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getId().equals(getGroupId())) { if (g.getGroup().getId().equals(getGroupId())) {
runOnUiThreadUnlessDestroyed( supportFinishAfterTransition();
this::supportFinishAfterTransition);
} }
} }
// TODO ContactConnectedEvent and ContactDisconnectedEvent // TODO ContactConnectedEvent and ContactDisconnectedEvent

View File

@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.android.DestroyableContext;
import org.briarproject.briar.android.controller.ActivityLifecycleController; import org.briarproject.briar.android.controller.ActivityLifecycleController;
import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.android.controller.handler.ExceptionHandler;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
@@ -52,7 +51,7 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem
void onInvitationAccepted(ContactId c); void onInvitationAccepted(ContactId c);
} }
interface ThreadListDataSource extends DestroyableContext { interface ThreadListDataSource {
@UiThread @Nullable @UiThread @Nullable
MessageId getFirstVisibleMessageId(); MessageId getFirstVisibleMessageId();

View File

@@ -50,15 +50,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
Logger.getLogger(ThreadListControllerImpl.class.getName()); Logger.getLogger(ThreadListControllerImpl.class.getName());
private final EventBus eventBus; private final EventBus eventBus;
private final MessageTracker messageTracker;
private final Map<MessageId, String> textCache = new ConcurrentHashMap<>(); private final Map<MessageId, String> textCache = new ConcurrentHashMap<>();
private volatile GroupId groupId; private volatile GroupId groupId;
protected final IdentityManager identityManager; protected final IdentityManager identityManager;
protected final AndroidNotificationManager notificationManager; protected final AndroidNotificationManager notificationManager;
protected final Executor cryptoExecutor; protected final Executor cryptoExecutor;
protected final Clock clock; protected final Clock clock;
private final MessageTracker messageTracker;
protected volatile L listener; // UI thread
protected L listener;
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor, protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, IdentityManager identityManager, LifecycleManager lifecycleManager, IdentityManager identityManager,
@@ -121,8 +124,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
GroupRemovedEvent s = (GroupRemovedEvent) e; GroupRemovedEvent s = (GroupRemovedEvent) e;
if (s.getGroup().getId().equals(getGroupId())) { if (s.getGroup().getId().equals(getGroupId())) {
LOG.info("Group removed"); LOG.info("Group removed");
listener.runOnUiThreadUnlessDestroyed( listener.onGroupRemoved();
() -> listener.onGroupRemoved());
} }
} }
} }