diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index ccca7563e6eb8d32105b6a7f467ed09423f53e3c..7cde33e7db29922bc9abc2c595a61a786e8a956d 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -387,13 +387,8 @@ implements EventListener, OnClickListener, OnItemClickListener { public void onClick(View view) { String message = content.getText().toString(); if(message.equals("")) return; - // Don't use an earlier timestamp than the newest message long timestamp = System.currentTimeMillis(); - int count = adapter.getCount(); - for(int i = 0; i < count; i++) { - long time = adapter.getItem(i).getHeader().getTimestamp() + 1; - if(time > timestamp) timestamp = time; - } + timestamp = Math.max(timestamp, getMinTimestampForNewMessage()); createMessage(StringUtils.toUtf8(message), timestamp); Toast.makeText(this, R.string.message_sent_toast, LENGTH_SHORT).show(); content.setText(""); @@ -402,6 +397,17 @@ implements EventListener, OnClickListener, OnItemClickListener { ((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0); } + private long getMinTimestampForNewMessage() { + // Don't use an earlier timestamp than the newest message + long timestamp = 0; + int count = adapter.getCount(); + for(int i = 0; i < count; i++) { + long t = adapter.getItem(i).getHeader().getTimestamp(); + if(t > timestamp) timestamp = t; + } + return timestamp + 1; + } + private void createMessage(final byte[] body, final long timestamp) { cryptoExecutor.execute(new Runnable() { public void run() { @@ -452,6 +458,7 @@ implements EventListener, OnClickListener, OnItemClickListener { i.putExtra("briar.MESSAGE_ID", header.getId().getBytes()); i.putExtra("briar.CONTENT_TYPE", header.getContentType()); i.putExtra("briar.TIMESTAMP", header.getTimestamp()); + i.putExtra("briar.MIN_TIMESTAMP", getMinTimestampForNewMessage()); i.putExtra("briar.POSITION", position); startActivityForResult(i, REQUEST_READ); } diff --git a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java index 19eeba26e43e35b7c70509e19eb8416e6a792a7a..2dfafbef4e74e5404dd305371f73e623bfed0ac2 100644 --- a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java @@ -51,6 +51,7 @@ implements OnClickListener { private String contactName = null; private AuthorId localAuthorId = null; + private long timestamp = -1, minTimestamp = -1; private ImageButton prevButton = null, nextButton = null; private ImageButton replyButton = null; private TextView content = null; @@ -60,7 +61,6 @@ implements OnClickListener { @Inject private volatile DatabaseComponent db; private volatile MessageId messageId = null; private volatile GroupId groupId = null; - private volatile long timestamp = -1; @Override public void onCreate(Bundle state) { @@ -85,6 +85,8 @@ implements OnClickListener { if(contentType == null) throw new IllegalStateException(); timestamp = i.getLongExtra("briar.TIMESTAMP", -1); if(timestamp == -1) throw new IllegalStateException(); + minTimestamp = i.getLongExtra("briar.MIN_TIMESTAMP", -1); + if(minTimestamp == -1) throw new IllegalStateException(); position = i.getIntExtra("briar.POSITION", -1); if(position == -1) throw new IllegalStateException(); @@ -228,7 +230,7 @@ implements OnClickListener { i.putExtra("briar.LOCAL_AUTHOR_ID", localAuthorId.getBytes()); i.putExtra("briar.PARENT_ID", messageId.getBytes()); - i.putExtra("briar.TIMESTAMP", timestamp); + i.putExtra("briar.MIN_TIMESTAMP", minTimestamp); startActivity(i); setResult(RESULT_REPLY); finish(); diff --git a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java index 9abb58bda8f8cceef13ad6cd2407838896b315fe..3c2d6ed33c1c711d679840108adfd6199f1205cd 100644 --- a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java +++ b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java @@ -69,7 +69,7 @@ implements OnClickListener { private volatile GroupId groupId = null; private volatile AuthorId localAuthorId = null; private volatile MessageId parentId = null; - private volatile long timestamp = -1; + private volatile long minTimestamp = -1; private volatile LocalAuthor localAuthor = null; private volatile Group group = null; @@ -86,10 +86,11 @@ implements OnClickListener { groupId = new GroupId(b); b = i.getByteArrayExtra("briar.LOCAL_AUTHOR_ID"); if(b == null) throw new IllegalStateException(); + minTimestamp = i.getLongExtra("briar.MIN_TIMESTAMP", -1); + if(minTimestamp == -1) throw new IllegalStateException(); localAuthorId = new AuthorId(b); b = i.getByteArrayExtra("briar.PARENT_ID"); if(b != null) parentId = new MessageId(b); - timestamp = i.getLongExtra("briar.TIMESTAMP", -1); LinearLayout layout = new LinearLayout(this); layout.setLayoutParams(MATCH_WRAP); @@ -187,12 +188,12 @@ implements OnClickListener { private void createMessage(final byte[] body) { cryptoExecutor.execute(new Runnable() { public void run() { - // Don't use an earlier timestamp than the parent - long time = System.currentTimeMillis(); - time = Math.max(time, timestamp + 1); + // Don't use an earlier timestamp than the newest message + long timestamp = System.currentTimeMillis(); + timestamp = Math.max(timestamp, minTimestamp); try { Message m = messageFactory.createAnonymousMessage(parentId, - group, "text/plain", time, body); + group, "text/plain", timestamp, body); storeMessage(m); } catch(GeneralSecurityException e) { throw new RuntimeException(e); diff --git a/briar-android/src/org/briarproject/android/groups/GroupActivity.java b/briar-android/src/org/briarproject/android/groups/GroupActivity.java index 89b519968959c7d8b2faf7f2de2a66d5167aceee..b82e5e4dbb0a4b065d5ec94b81c78d1acd0dc09b 100644 --- a/briar-android/src/org/briarproject/android/groups/GroupActivity.java +++ b/briar-android/src/org/briarproject/android/groups/GroupActivity.java @@ -318,9 +318,21 @@ OnClickListener, OnItemClickListener { Intent i = new Intent(this, WriteGroupPostActivity.class); i.putExtra("briar.GROUP_ID", groupId.getBytes()); i.putExtra("briar.GROUP_NAME", groupName); + i.putExtra("briar.MIN_TIMESTAMP", getMinTimestampForNewMessage()); startActivity(i); } + private long getMinTimestampForNewMessage() { + // Don't use an earlier timestamp than the newest message + long timestamp = 0; + int count = adapter.getCount(); + for(int i = 0; i < count; i++) { + long t = adapter.getItem(i).getHeader().getTimestamp(); + if(t > timestamp) timestamp = t; + } + return timestamp + 1; + } + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { displayMessage(position); @@ -337,6 +349,7 @@ OnClickListener, OnItemClickListener { i.putExtra("briar.AUTHOR_STATUS", item.getAuthorStatus().name()); i.putExtra("briar.CONTENT_TYPE", item.getContentType()); i.putExtra("briar.TIMESTAMP", item.getTimestamp()); + i.putExtra("briar.MIN_TIMESTAMP", getMinTimestampForNewMessage()); i.putExtra("briar.POSITION", position); startActivityForResult(i, REQUEST_READ); } diff --git a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java index 5ebfb1aa50eb68348fcdbac69abcc68ad292a323..25a0a3d05dd4f628a04673daa3de33c6c714056d 100644 --- a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java +++ b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java @@ -50,6 +50,7 @@ implements OnClickListener { private GroupId groupId = null; private String groupName = null; + private long timestamp = -1, minTimestamp = -1; private ImageButton prevButton = null, nextButton = null; private ImageButton replyButton = null; private TextView content = null; @@ -58,7 +59,6 @@ implements OnClickListener { // Fields that are accessed from background threads must be volatile @Inject private volatile DatabaseComponent db; private volatile MessageId messageId = null; - private volatile long timestamp = -1; @Override public void onCreate(Bundle state) { @@ -78,6 +78,8 @@ implements OnClickListener { if(contentType == null) throw new IllegalStateException(); timestamp = i.getLongExtra("briar.TIMESTAMP", -1); if(timestamp == -1) throw new IllegalStateException(); + minTimestamp = i.getLongExtra("briar.MIN_TIMESTAMP", -1); + if(minTimestamp == -1) throw new IllegalStateException(); position = i.getIntExtra("briar.POSITION", -1); if(position == -1) throw new IllegalStateException(); String authorName = i.getStringExtra("briar.AUTHOR_NAME"); @@ -223,7 +225,7 @@ implements OnClickListener { i.putExtra("briar.GROUP_ID", groupId.getBytes()); i.putExtra("briar.GROUP_NAME", groupName); i.putExtra("briar.PARENT_ID", messageId.getBytes()); - i.putExtra("briar.TIMESTAMP", timestamp); + i.putExtra("briar.MIN_TIMESTAMP", minTimestamp); startActivity(i); setResult(RESULT_REPLY); finish(); diff --git a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java index 76bc207bc954adb72c6a9cecc061a2a2f84f04b5..27d8f92852f7bb4431ac5eec5eb3d0e26120aa04 100644 --- a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java +++ b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java @@ -79,7 +79,7 @@ implements OnItemSelectedListener, OnClickListener { @Inject private volatile CryptoComponent crypto; @Inject private volatile MessageFactory messageFactory; private volatile MessageId parentId = null; - private volatile long timestamp = -1; + private volatile long minTimestamp = -1; private volatile LocalAuthor localAuthor = null; private volatile Group group = null; @@ -94,9 +94,10 @@ implements OnItemSelectedListener, OnClickListener { String groupName = i.getStringExtra("briar.GROUP_NAME"); if(groupName == null) throw new IllegalStateException(); setTitle(groupName); + minTimestamp = i.getLongExtra("briar.MIN_TIMESTAMP", -1); + if(minTimestamp == -1) throw new IllegalStateException(); b = i.getByteArrayExtra("briar.PARENT_ID"); if(b != null) parentId = new MessageId(b); - timestamp = i.getLongExtra("briar.TIMESTAMP", -1); if(state != null) { b = state.getByteArray("briar.LOCAL_AUTHOR_ID"); @@ -260,21 +261,21 @@ implements OnItemSelectedListener, OnClickListener { private void createMessage(final byte[] body) { cryptoExecutor.execute(new Runnable() { public void run() { - // Don't use an earlier timestamp than the parent - long time = System.currentTimeMillis(); - time = Math.max(time, timestamp + 1); + // Don't use an earlier timestamp than the newest post + long timestamp = System.currentTimeMillis(); + timestamp = Math.max(timestamp, minTimestamp); Message m; try { if(localAuthor == null) { m = messageFactory.createAnonymousMessage(parentId, - group, "text/plain", time, body); + group, "text/plain", timestamp, body); } else { KeyParser keyParser = crypto.getSignatureKeyParser(); byte[] b = localAuthor.getPrivateKey(); PrivateKey authorKey = keyParser.parsePrivateKey(b); m = messageFactory.createPseudonymousMessage(parentId, group, localAuthor, authorKey, "text/plain", - time, body); + timestamp, body); } } catch(GeneralSecurityException e) { throw new RuntimeException(e);