Posting group messages takes previous message into account

This commit is contained in:
Torsten Grote
2016-10-20 16:34:11 -02:00
parent 4f4f1956eb
commit 2c8aaa215c
5 changed files with 100 additions and 87 deletions

View File

@@ -3,6 +3,7 @@ package org.briarproject.android.forum;
import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.crypto.CryptoExecutor;
@@ -28,8 +29,11 @@ import java.util.logging.Logger;
import javax.inject.Inject;
public class ForumControllerImpl extends
ThreadListControllerImpl<Forum, ForumItem, ForumPostHeader, ForumPost>
import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
public class ForumControllerImpl
extends ThreadListControllerImpl<Forum, ForumItem, ForumPostHeader, ForumPost>
implements ForumController {
private static final Logger LOG =
@@ -42,9 +46,9 @@ public class ForumControllerImpl extends
LifecycleManager lifecycleManager, IdentityManager identityManager,
@CryptoExecutor Executor cryptoExecutor,
ForumManager forumManager, EventBus eventBus,
AndroidNotificationManager notificationManager, Clock clock) {
Clock clock, AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager, identityManager, cryptoExecutor,
eventBus, notificationManager, clock);
eventBus, clock, notificationManager);
this.forumManager = forumManager;
}
@@ -94,16 +98,42 @@ public class ForumControllerImpl extends
}
@Override
protected long getLatestTimestamp() throws DbException {
GroupCount count = forumManager.getGroupCount(getGroupId());
return count.getLatestMsgTime();
public void createAndStoreMessage(final String body,
@Nullable final ForumItem parentItem,
final ResultExceptionHandler<ForumItem, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LocalAuthor author = identityManager.getLocalAuthor();
GroupCount count = forumManager.getGroupCount(getGroupId());
long timestamp = max(count.getLatestMsgTime() + 1,
clock.currentTimeMillis());
MessageId parentId = parentItem != null ?
parentItem.getId() : null;
createMessage(body, timestamp, parentId, author, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
}
@Override
protected ForumPost createLocalMessage(String body, long timestamp,
@Nullable MessageId parentId, LocalAuthor author) {
return forumManager.createLocalPost(getGroupId(), body, timestamp,
parentId, author);
private void createMessage(final String body, final long timestamp,
final @Nullable MessageId parentId, final LocalAuthor author,
final ResultExceptionHandler<ForumItem, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
LOG.info("Creating forum post...");
ForumPost msg = forumManager
.createLocalPost(getGroupId(), body, timestamp,
parentId, author);
storePost(msg, body, handler);
}
});
}
@Override

View File

@@ -3,8 +3,8 @@ package org.briarproject.android.privategroup.conversation;
import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
@@ -28,6 +28,9 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
public class GroupControllerImpl extends
ThreadListControllerImpl<PrivateGroup, GroupMessageItem, GroupMessageHeader, GroupMessage>
implements GroupController {
@@ -44,9 +47,9 @@ public class GroupControllerImpl extends
@CryptoExecutor Executor cryptoExecutor,
PrivateGroupManager privateGroupManager,
GroupMessageFactory groupMessageFactory, EventBus eventBus,
AndroidNotificationManager notificationManager, Clock clock) {
Clock clock, AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager, identityManager, cryptoExecutor,
eventBus, notificationManager, clock);
eventBus, clock, notificationManager);
this.privateGroupManager = privateGroupManager;
this.groupMessageFactory = groupMessageFactory;
}
@@ -97,18 +100,52 @@ public class GroupControllerImpl extends
}
@Override
protected long getLatestTimestamp() throws DbException {
GroupCount count = privateGroupManager.getGroupCount(getGroupId());
return count.getLatestMsgTime();
public void createAndStoreMessage(final String body,
@Nullable final GroupMessageItem parentItem,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LocalAuthor author = identityManager.getLocalAuthor();
MessageId parentId = null;
MessageId previousMsgId =
privateGroupManager.getPreviousMsgId(getGroupId());
// timestamp must be greater than the timestamps
// of the member's previous message...
long timestamp = privateGroupManager
.getMessageTimestamp(previousMsgId);
// ...and the parent post, if any
if (parentItem != null) {
timestamp = max(parentItem.getTimestamp(), timestamp);
parentId = parentItem.getId();
}
timestamp = max(clock.currentTimeMillis(), timestamp + 1);
createMessage(body, timestamp, parentId, author,
previousMsgId, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
}
@Override
protected GroupMessage createLocalMessage(String body, long timestamp,
@Nullable MessageId parentId, LocalAuthor author) {
MessageId previousMsgId = null; // TODO
return groupMessageFactory
.createGroupMessage(getGroupId(), timestamp, parentId,
author, body, previousMsgId);
private void createMessage(final String body, final long timestamp,
final @Nullable MessageId parentId, final LocalAuthor author,
final MessageId previousMsgId,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
LOG.info("Creating group message...");
GroupMessage msg = groupMessageFactory
.createGroupMessage(getGroupId(), timestamp,
parentId, author, body, previousMsgId);
storePost(msg, body, handler);
}
});
}
@Override

View File

@@ -249,8 +249,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
finish();
}
};
getController().createAndStoreMessage(text,
replyItem != null ? replyItem.getId() : null, handler);
getController().createAndStoreMessage(text, replyItem, handler);
textInput.hideSoftKeyboard();
textInput.setVisibility(GONE);
textInput.setText("");

View File

@@ -10,7 +10,6 @@ import org.briarproject.api.clients.NamedGroup;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import java.util.Collection;
@@ -29,7 +28,7 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem
void markItemsRead(Collection<I> items);
void createAndStoreMessage(String body, @Nullable MessageId parentId,
void createAndStoreMessage(String body, @Nullable I parentItem,
ResultExceptionHandler<I, DbException> handler);
void deleteNamedGroup(ResultExceptionHandler<Void, DbException> handler);

View File

@@ -2,7 +2,6 @@ package org.briarproject.android.threaded;
import android.app.Activity;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.DbControllerImpl;
@@ -18,7 +17,6 @@ import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
@@ -43,12 +41,12 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
private static final Logger LOG =
Logger.getLogger(ThreadListControllerImpl.class.getName());
private final IdentityManager identityManager;
protected final IdentityManager identityManager;
@CryptoExecutor
private final Executor cryptoExecutor;
protected final Executor cryptoExecutor;
protected final AndroidNotificationManager notificationManager;
protected final Clock clock;
private final EventBus eventBus;
private final Clock clock;
private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
@@ -59,13 +57,13 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, IdentityManager identityManager,
@CryptoExecutor Executor cryptoExecutor, EventBus eventBus,
AndroidNotificationManager notificationManager, Clock clock) {
Clock clock, AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager);
this.identityManager = identityManager;
this.cryptoExecutor = cryptoExecutor;
this.eventBus = eventBus;
this.notificationManager = notificationManager;
this.clock = clock;
this.eventBus = eventBus;
}
@Override
@@ -243,57 +241,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
@DatabaseExecutor
protected abstract void markRead(MessageId id) throws DbException;
@Override
public void createAndStoreMessage(final String body,
@Nullable final MessageId parentId,
final ResultExceptionHandler<I, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
long now = System.currentTimeMillis();
LocalAuthor author = identityManager.getLocalAuthor();
long timestamp = getLatestTimestamp();
timestamp = Math.max(timestamp, clock.currentTimeMillis());
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) {
LOG.info("Loading identity and timestamp took " +
duration + " ms");
}
createMessage(body, timestamp, parentId, author, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
}
@DatabaseExecutor
protected abstract long getLatestTimestamp() throws DbException;
private void createMessage(final String body, final long timestamp,
final @Nullable MessageId parentId, final LocalAuthor author,
final ResultExceptionHandler<I, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
long now = System.currentTimeMillis();
M msg = createLocalMessage(body, timestamp, parentId, author);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Creating message took " + duration + " ms");
storePost(msg, body, handler);
}
});
}
@CryptoExecutor
protected abstract M createLocalMessage(String body, long timestamp,
@Nullable MessageId parentId, LocalAuthor author);
private void storePost(final M msg, final String body,
protected void storePost(final M msg, final String body,
final ResultExceptionHandler<I, DbException> resultHandler) {
runOnDbThread(new Runnable() {
@Override