diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/autodelete/AutoDeleteConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/autodelete/AutoDeleteConstants.java index 73db007ba..ca1aaaf8e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/autodelete/AutoDeleteConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/autodelete/AutoDeleteConstants.java @@ -5,7 +5,19 @@ import static java.util.concurrent.TimeUnit.MINUTES; public interface AutoDeleteConstants { + /** + * The minimum valid auto-delete timer duration in milliseconds. + */ long MIN_AUTO_DELETE_TIMER_MS = MINUTES.toMillis(1); + /** + * The maximum valid auto-delete timer duration in milliseconds. + */ long MAX_AUTO_DELETE_TIMER_MS = DAYS.toMillis(365); + + /** + * Placeholder value indicating that a message has no auto-delete timer. + * This value should not be sent over the wire - send null instead. + */ + long NO_AUTO_DELETE_TIMER = -1; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index 9c8f21d26..a741cf5bb 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -140,7 +140,7 @@ import static org.briarproject.briar.android.util.UiUtils.getBulbTransitionName; import static org.briarproject.briar.android.util.UiUtils.observeOnce; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH; -import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT; +import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -275,7 +275,7 @@ public class ConversationActivity extends BriarActivity sendController = new TextAttachmentController(textInputView, imagePreview, this, viewModel); observeOnce(viewModel.getPrivateMessageFormat(), this, format -> { - if (format != null && format != TEXT) { + if (format != TEXT_ONLY) { // TODO: remove cast when removing feature flag ((TextAttachmentController) sendController) .setImagesSupported(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java index 85d450964..9f2e034a6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java @@ -53,13 +53,14 @@ import androidx.lifecycle.Transformations; import static java.util.Objects.requireNonNull; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce; -import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES; +import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY; @NotNullByDefault public class ConversationViewModel extends AndroidViewModel @@ -256,7 +257,7 @@ public class ConversationViewModel extends AndroidViewModel // we only show one onboarding dialog at a time Settings settings = settingsManager.getSettings(SETTINGS_NAMESPACE); - if (format != TEXT && + if (format != TEXT_ONLY && settings.getBoolean(SHOW_ONBOARDING_IMAGE, true)) { onOnboardingShown(SHOW_ONBOARDING_IMAGE); showImageOnboarding.postEvent(true); @@ -280,7 +281,7 @@ public class ConversationViewModel extends AndroidViewModel PrivateMessageFormat format) { try { PrivateMessage pm; - if (format == TEXT) { + if (format == TEXT_ONLY) { pm = privateMessageFactory.createLegacyPrivateMessage( groupId, timestamp, requireNonNull(text)); } else if (format == TEXT_IMAGES) { @@ -289,7 +290,7 @@ public class ConversationViewModel extends AndroidViewModel } else { // TODO: Look up auto-delete timer pm = privateMessageFactory.createPrivateMessage(groupId, - timestamp, text, headers, -1); + timestamp, text, headers, NO_AUTO_DELETE_TIMER); } storeMessage(pm); } catch (FormatException e) { diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java index b5af67f03..f9d17c6c1 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java @@ -8,9 +8,10 @@ import java.util.List; import javax.annotation.concurrent.Immutable; import static java.util.Collections.emptyList; -import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE; +import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY; @Immutable @NotNullByDefault @@ -24,14 +25,14 @@ public class PrivateMessage { /** * Constructor for private messages in the - * {@link PrivateMessageFormat#TEXT TEXT} format. + * {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format. */ public PrivateMessage(Message message) { this.message = message; hasText = true; attachmentHeaders = emptyList(); - autoDeleteTimer = -1; - format = TEXT; + autoDeleteTimer = NO_AUTO_DELETE_TIMER; + format = TEXT_ONLY; } /** @@ -43,7 +44,7 @@ public class PrivateMessage { this.message = message; this.hasText = hasText; this.attachmentHeaders = headers; - autoDeleteTimer = -1; + autoDeleteTimer = NO_AUTO_DELETE_TIMER; format = TEXT_IMAGES; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFactory.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFactory.java index 7128bd778..0215bafcb 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFactory.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFactory.java @@ -11,13 +11,28 @@ import javax.annotation.Nullable; @NotNullByDefault public interface PrivateMessageFactory { + /** + * Creates a private message in the + * {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format. + */ PrivateMessage createLegacyPrivateMessage(GroupId groupId, long timestamp, String text) throws FormatException; + /** + * Creates a private message in the + * {@link PrivateMessageFormat#TEXT_IMAGES TEXT_IMAGES} format. This format + * requires the contact to support client version 0.1 or higher. + */ PrivateMessage createPrivateMessage(GroupId groupId, long timestamp, @Nullable String text, List headers) throws FormatException; + /** + * Creates a private message in the + * {@link PrivateMessageFormat#TEXT_IMAGES_AUTO_DELETE TEXT_IMAGES_AUTO_DELETE} + * format. This format requires the contact to support client version 0.3 + * or higher. + */ PrivateMessage createPrivateMessage(GroupId groupId, long timestamp, @Nullable String text, List headers, long autoDeleteTimer) throws FormatException; diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFormat.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFormat.java index 6982e0b31..b7f08b9f3 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFormat.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageFormat.java @@ -6,7 +6,7 @@ public enum PrivateMessageFormat { * First version of the private message format, which doesn't support * image attachments or auto-deletion. */ - TEXT, + TEXT_ONLY, /** * Second version of the private message format, which supports image diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java index 7eaf2faf5..fac667ecf 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java @@ -58,12 +58,13 @@ import javax.annotation.concurrent.Immutable; import javax.inject.Inject; import static java.util.Collections.emptyList; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.util.IoUtils.copyAndClose; -import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE; +import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY; import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ; import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT; import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE; @@ -201,7 +202,8 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, long timestamp = meta.getLong(MSG_KEY_TIMESTAMP); boolean local = meta.getBoolean(MSG_KEY_LOCAL); boolean read = meta.getBoolean(MSG_KEY_READ); - long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, -1L); + long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, + NO_AUTO_DELETE_TIMER); PrivateMessageHeader header = new PrivateMessageHeader(m.getId(), groupId, timestamp, local, read, false, false, hasText, headers, timer); @@ -240,7 +242,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, meta.put(MSG_KEY_TIMESTAMP, m.getMessage().getTimestamp()); meta.put(MSG_KEY_LOCAL, true); meta.put(MSG_KEY_READ, true); - if (m.getFormat() != TEXT) { + if (m.getFormat() != TEXT_ONLY) { meta.put(MSG_KEY_MSG_TYPE, PRIVATE_MESSAGE); meta.put(MSG_KEY_HAS_TEXT, m.hasText()); BdfList headers = new BdfList(); @@ -251,7 +253,9 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, meta.put(MSG_KEY_ATTACHMENT_HEADERS, headers); if (m.getFormat() == TEXT_IMAGES_AUTO_DELETE) { long timer = m.getAutoDeleteTimer(); - if (timer != -1) meta.put(MSG_KEY_AUTO_DELETE_TIMER, timer); + if (timer != NO_AUTO_DELETE_TIMER) { + meta.put(MSG_KEY_AUTO_DELETE_TIMER, timer); + } } } // Mark attachments as shared and permanent now we're ready to send @@ -365,10 +369,11 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, if (messageType == null) { headers.add(new PrivateMessageHeader(id, g, timestamp, local, read, s.isSent(), s.isSeen(), true, - emptyList(), -1)); + emptyList(), NO_AUTO_DELETE_TIMER)); } else { boolean hasText = meta.getBoolean(MSG_KEY_HAS_TEXT); - long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, -1L); + long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, + NO_AUTO_DELETE_TIMER); headers.add(new PrivateMessageHeader(id, g, timestamp, local, read, s.isSent(), s.isSeen(), hasText, parseAttachmentHeaders(meta), timer)); @@ -439,7 +444,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, .getClientMinorVersion(txn, c, CLIENT_ID, 0); if (minorVersion >= 3) return TEXT_IMAGES_AUTO_DELETE; else if (minorVersion >= 1) return TEXT_IMAGES; - else return TEXT; + else return TEXT_ONLY; } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java index ec60e4c91..4c330db48 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java @@ -16,6 +16,7 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH; import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE; @@ -52,7 +53,7 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory { // Serialise the message BdfList body = BdfList.of(PRIVATE_MESSAGE, text, attachmentList); Message m = clientHelper.createMessage(groupId, timestamp, body); - return new PrivateMessage(m, text != null, headers, -1); + return new PrivateMessage(m, text != null, headers); } @Override @@ -62,7 +63,8 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory { validateTextAndAttachmentHeaders(text, headers); BdfList attachmentList = serialiseAttachmentHeaders(headers); // Serialise the message - Long timer = autoDeleteTimer == -1 ? null : autoDeleteTimer; + Long timer = autoDeleteTimer == NO_AUTO_DELETE_TIMER ? + null : autoDeleteTimer; BdfList body = BdfList.of(PRIVATE_MESSAGE, text, attachmentList, timer); Message m = clientHelper.createMessage(groupId, timestamp, body); return new PrivateMessage(m, text != null, headers, autoDeleteTimer); diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java index 4588e8f2b..9f3e71f94 100644 --- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java @@ -55,6 +55,7 @@ import static java.util.Collections.emptyList; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.util.StringUtils.getRandomString; @@ -324,7 +325,8 @@ public class TestDataCreatorImpl implements TestDataCreator { private void createPrivateMessage(GroupId groupId, String text, long timestamp, boolean local, boolean autoDelete) throws DbException, FormatException { - long timer = autoDelete ? MIN_AUTO_DELETE_TIMER_MS : -1; + long timer = autoDelete ? + MIN_AUTO_DELETE_TIMER_MS : NO_AUTO_DELETE_TIMER; PrivateMessage m = privateMessageFactory.createPrivateMessage(groupId, timestamp, text, emptyList(), timer); BdfDictionary meta = new BdfDictionary(); diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/MessagingManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/MessagingManagerIntegrationTest.java index f754489fc..bf42ff5ed 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/MessagingManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/MessagingManagerIntegrationTest.java @@ -33,6 +33,7 @@ import static java.util.Collections.emptySet; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; @@ -111,8 +112,8 @@ public class MessagingManagerIntegrationTest assertTrue(m1.hasText()); assertEquals(0, m0.getAttachmentHeaders().size()); assertEquals(0, m1.getAttachmentHeaders().size()); - assertEquals(-1, m0.getAutoDeleteTimer()); - assertEquals(-1, m1.getAutoDeleteTimer()); + assertEquals(NO_AUTO_DELETE_TIMER, m0.getAutoDeleteTimer()); + assertEquals(NO_AUTO_DELETE_TIMER, m1.getAutoDeleteTimer()); assertTrue(m0.isRead()); assertFalse(m1.isRead()); assertGroupCounts(c0, 1, 0); @@ -148,8 +149,8 @@ public class MessagingManagerIntegrationTest assertFalse(m1.hasText()); assertEquals(1, m0.getAttachmentHeaders().size()); assertEquals(1, m1.getAttachmentHeaders().size()); - assertEquals(-1, m0.getAutoDeleteTimer()); - assertEquals(-1, m1.getAutoDeleteTimer()); + assertEquals(NO_AUTO_DELETE_TIMER, m0.getAutoDeleteTimer()); + assertEquals(NO_AUTO_DELETE_TIMER, m1.getAutoDeleteTimer()); assertTrue(m0.isRead()); assertFalse(m1.isRead()); assertGroupCounts(c0, 1, 0); @@ -374,7 +375,7 @@ public class MessagingManagerIntegrationTest private PrivateMessage sendMessage(BriarIntegrationTestComponent from, BriarIntegrationTestComponent to, @Nullable String text, List attachments) throws Exception { - return sendMessage(from, to, text, attachments, -1); + return sendMessage(from, to, text, attachments, NO_AUTO_DELETE_TIMER); } private PrivateMessage sendMessage(BriarIntegrationTestComponent from, diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java index 5ba79e141..dff4034ff 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.CountDownLatch; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; @@ -123,7 +124,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { PrivateMessageFactory privateMessageFactory = device.getPrivateMessageFactory(); PrivateMessage message = privateMessageFactory.createPrivateMessage( - groupId, timestamp, "Hi!", singletonList(attachmentHeader), -1); + groupId, timestamp, "Hi!", singletonList(attachmentHeader), + NO_AUTO_DELETE_TIMER); messagingManager.addLocalMessage(message); } diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/event/WebSocketControllerTest.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/event/WebSocketControllerTest.kt index 103942d7e..4d423305d 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/event/WebSocketControllerTest.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/event/WebSocketControllerTest.kt @@ -6,6 +6,7 @@ import io.mockk.CapturingSlot import io.mockk.every import io.mockk.mockk import io.mockk.verify +import org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER import org.briarproject.bramble.api.identity.AuthorInfo import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED import org.briarproject.bramble.test.ImmediateExecutor @@ -42,7 +43,7 @@ internal class WebSocketControllerTest : ControllerTest() { true, true, emptyList(), - -1 + NO_AUTO_DELETE_TIMER ) private val event = PrivateMessageReceivedEvent(header, contact.id) private val outputEvent = OutputEvent(EVENT_CONVERSATION_MESSAGE, event.output(text)) diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt index 3c47d1ae9..2f1e451f3 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt @@ -11,6 +11,7 @@ import io.mockk.just import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.runs +import org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER import org.briarproject.bramble.api.contact.ContactId import org.briarproject.bramble.api.db.NoSuchContactException import org.briarproject.bramble.api.identity.AuthorInfo @@ -69,7 +70,7 @@ internal class MessagingControllerImplTest : ControllerTest() { true, true, emptyList(), - -1 + NO_AUTO_DELETE_TIMER ) private val sessionId = SessionId(getRandomId()) private val privateMessage = PrivateMessage(message)