diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java index 24295f22f..aacd95ffb 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java @@ -40,9 +40,9 @@ import org.briarproject.briar.android.splash.SplashScreenActivity; import org.briarproject.briar.android.util.BriarNotificationBuilder; import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.blog.event.BlogPostAddedEvent; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent; -import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent; import java.util.Set; @@ -219,8 +219,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; if (s.getNamespace().equals(SETTINGS_NAMESPACE)) settings = s.getSettings(); - } else if (e instanceof PrivateMessageReceivedEvent) { - PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; + } else if (e instanceof ConversationMessageReceivedEvent) { + ConversationMessageReceivedEvent p = + (ConversationMessageReceivedEvent) e; showContactNotification(p.getContactId()); } else if (e instanceof GroupMessageAddedEvent) { GroupMessageAddedEvent g = (GroupMessageAddedEvent) e; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java index d08bec390..497da8b85 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java @@ -37,8 +37,8 @@ import org.briarproject.briar.android.view.BriarRecyclerView; import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.conversation.ConversationManager; -import org.briarproject.briar.api.messaging.PrivateMessageHeader; -import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; +import org.briarproject.briar.api.conversation.ConversationMessageHeader; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; import java.util.ArrayList; import java.util.List; @@ -242,15 +242,16 @@ public class ContactListFragment extends BaseFragment implements EventListener { } else if (e instanceof ContactRemovedEvent) { LOG.info("Contact removed, removing item"); removeItem(((ContactRemovedEvent) e).getContactId()); - } else if (e instanceof PrivateMessageReceivedEvent) { - LOG.info("Private message received, updating item"); - PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; - PrivateMessageHeader h = p.getMessageHeader(); + } else if (e instanceof ConversationMessageReceivedEvent) { + LOG.info("Conversation message received, updating item"); + ConversationMessageReceivedEvent p = + (ConversationMessageReceivedEvent) e; + ConversationMessageHeader h = p.getMessageHeader(); updateItem(p.getContactId(), h); } } - private void updateItem(ContactId c, PrivateMessageHeader h) { + private void updateItem(ContactId c, ConversationMessageHeader h) { runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision(); int position = adapter.findItemPosition(c); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java index 7e910358c..7b0fc0328 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android.contact; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.client.MessageTracker.GroupCount; -import org.briarproject.briar.api.messaging.PrivateMessageHeader; +import org.briarproject.briar.api.conversation.ConversationMessageHeader; import javax.annotation.concurrent.NotThreadSafe; @@ -23,7 +23,7 @@ public class ContactListItem extends ContactItem { this.timestamp = count.getLatestMsgTime(); } - void addMessage(PrivateMessageHeader h) { + void addMessage(ConversationMessageHeader h) { empty = false; if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp(); if (!h.isRead()) unread++; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java index 75a1f3279..8fe29cbe6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java @@ -67,13 +67,13 @@ import org.briarproject.briar.api.conversation.ConversationManager; import org.briarproject.briar.api.conversation.ConversationMessageHeader; import org.briarproject.briar.api.conversation.ConversationRequest; import org.briarproject.briar.api.conversation.ConversationResponse; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; import org.briarproject.briar.api.forum.ForumSharingManager; import org.briarproject.briar.api.introduction.IntroductionManager; import org.briarproject.briar.api.messaging.MessagingManager; import org.briarproject.briar.api.messaging.PrivateMessage; import org.briarproject.briar.api.messaging.PrivateMessageFactory; import org.briarproject.briar.api.messaging.PrivateMessageHeader; -import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; import java.util.ArrayList; @@ -410,11 +410,12 @@ public class ConversationActivity extends BriarActivity LOG.info("Contact removed"); finishOnUiThread(); } - } else if (e instanceof PrivateMessageReceivedEvent) { - PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; + } else if (e instanceof ConversationMessageReceivedEvent) { + ConversationMessageReceivedEvent p = + (ConversationMessageReceivedEvent) e; if (p.getContactId().equals(contactId)) { LOG.info("Message received, adding"); - onNewPrivateMessage(p.getMessageHeader()); + onNewConversationMessage(p.getMessageHeader()); } } else if (e instanceof MessagesSentEvent) { MessagesSentEvent m = (MessagesSentEvent) e; @@ -452,7 +453,7 @@ public class ConversationActivity extends BriarActivity }); } - private void onNewPrivateMessage(ConversationMessageHeader h) { + private void onNewConversationMessage(ConversationMessageHeader h) { runOnUiThreadUnlessDestroyed(() -> { if (h instanceof ConversationRequest || h instanceof ConversationResponse) { diff --git a/briar-api/src/main/java/org/briarproject/briar/api/conversation/event/ConversationMessageReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/conversation/event/ConversationMessageReceivedEvent.java index cee4a48ad..b0a04097b 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/conversation/event/ConversationMessageReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/conversation/event/ConversationMessageReceivedEvent.java @@ -12,7 +12,7 @@ import javax.annotation.concurrent.Immutable; */ @Immutable @NotNullByDefault -public class ConversationMessageReceivedEvent +public abstract class ConversationMessageReceivedEvent extends Event { private final H messageHeader; diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/event/OutputEvent.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/event/OutputEvent.kt index aade73835..976749b40 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/event/OutputEvent.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/event/OutputEvent.kt @@ -1,13 +1,41 @@ package org.briarproject.briar.headless.event +import org.briarproject.briar.api.blog.BlogInvitationRequest +import org.briarproject.briar.api.blog.BlogInvitationResponse import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent +import org.briarproject.briar.api.forum.ForumInvitationRequest +import org.briarproject.briar.api.forum.ForumInvitationResponse +import org.briarproject.briar.api.introduction.IntroductionRequest +import org.briarproject.briar.api.introduction.IntroductionResponse +import org.briarproject.briar.api.messaging.PrivateMessageHeader +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse +import org.briarproject.briar.headless.json.JsonDict import org.briarproject.briar.headless.messaging.output import javax.annotation.concurrent.Immutable @Immutable -internal class OutputEvent(val name: String, val data: Any) { +@Suppress("unused") +internal class OutputEvent(val name: String, val data: JsonDict) { val type = "event" } -internal fun ConversationMessageReceivedEvent<*>.output(text: String) = - messageHeader.output(contactId, text) +internal fun ConversationMessageReceivedEvent<*>.output(text: String): JsonDict { + check(messageHeader is PrivateMessageHeader) + return (messageHeader as PrivateMessageHeader).output(contactId, text) +} + +internal fun ConversationMessageReceivedEvent<*>.output() = when (messageHeader) { + // requests + is ForumInvitationRequest -> (messageHeader as ForumInvitationRequest).output(contactId) + is BlogInvitationRequest -> (messageHeader as BlogInvitationRequest).output(contactId) + is GroupInvitationRequest -> (messageHeader as GroupInvitationRequest).output(contactId) + is IntroductionRequest -> (messageHeader as IntroductionRequest).output(contactId) + // responses + is ForumInvitationResponse -> (messageHeader as ForumInvitationResponse).output(contactId) + is BlogInvitationResponse -> (messageHeader as BlogInvitationResponse).output(contactId) + is GroupInvitationResponse -> (messageHeader as GroupInvitationResponse).output(contactId) + is IntroductionResponse -> (messageHeader as IntroductionResponse).output(contactId) + // unknown + else -> throw IllegalStateException() +} diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/MessagingControllerImpl.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/MessagingControllerImpl.kt index bb5085496..ea9d5c735 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/MessagingControllerImpl.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/MessagingControllerImpl.kt @@ -38,7 +38,7 @@ import javax.annotation.concurrent.Immutable import javax.inject.Inject import javax.inject.Singleton -internal const val EVENT_PRIVATE_MESSAGE = "ConversationMessageReceivedEvent" +internal const val EVENT_CONVERSATION_MESSAGE = "ConversationMessageReceivedEvent" @Immutable @Singleton @@ -82,8 +82,13 @@ constructor( override fun eventOccurred(e: Event) { when (e) { is ConversationMessageReceivedEvent<*> -> dbExecutor.execute { - val text = messagingManager.getMessageText(e.messageHeader.id) - webSocketController.sendEvent(EVENT_PRIVATE_MESSAGE, e.output(text)) + val h = e.messageHeader + if (h is PrivateMessageHeader) { + val text = messagingManager.getMessageText(h.id) + webSocketController.sendEvent(EVENT_CONVERSATION_MESSAGE, e.output(text)) + } else { + webSocketController.sendEvent(EVENT_CONVERSATION_MESSAGE, e.output()) + } } } } diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateMessage.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationMessage.kt similarity index 79% rename from briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateMessage.kt rename to briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationMessage.kt index f4c3199a7..192d0439a 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateMessage.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationMessage.kt @@ -3,10 +3,10 @@ package org.briarproject.briar.headless.messaging import org.briarproject.bramble.api.contact.ContactId import org.briarproject.briar.api.conversation.ConversationMessageHeader import org.briarproject.briar.api.messaging.PrivateMessage +import org.briarproject.briar.api.messaging.PrivateMessageHeader import org.briarproject.briar.headless.json.JsonDict internal fun ConversationMessageHeader.output(contactId: ContactId) = JsonDict( - "type" to "PrivateMessage", "contactId" to contactId.int, "timestamp" to timestamp, "read" to isRead, @@ -23,6 +23,14 @@ internal fun ConversationMessageHeader.output(contactId: ContactId, text: String return dict } +internal fun PrivateMessageHeader.output(contactId: ContactId, text: String?): JsonDict { + val dict = (this as ConversationMessageHeader).output(contactId, text) + dict.putAll( + "type" to "PrivateMessage" + ) + return dict +} + /** * Use only for outgoing messages that were just sent */ diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateRequest.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationRequest.kt similarity index 100% rename from briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateRequest.kt rename to briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationRequest.kt diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateResponse.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationResponse.kt similarity index 93% rename from briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateResponse.kt rename to briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationResponse.kt index a567b092a..017363b35 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputPrivateResponse.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/messaging/OutputConversationResponse.kt @@ -3,16 +3,16 @@ package org.briarproject.briar.headless.messaging import org.briarproject.bramble.api.contact.ContactId import org.briarproject.bramble.identity.output import org.briarproject.briar.api.blog.BlogInvitationResponse +import org.briarproject.briar.api.conversation.ConversationMessageHeader +import org.briarproject.briar.api.conversation.ConversationResponse import org.briarproject.briar.api.forum.ForumInvitationResponse import org.briarproject.briar.api.introduction.IntroductionResponse -import org.briarproject.briar.api.messaging.PrivateMessageHeader -import org.briarproject.briar.api.conversation.ConversationResponse import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse import org.briarproject.briar.api.sharing.InvitationResponse import org.briarproject.briar.headless.json.JsonDict internal fun ConversationResponse.output(contactId: ContactId): JsonDict { - val dict = (this as PrivateMessageHeader).output(contactId) + val dict = (this as ConversationMessageHeader).output(contactId) dict.putAll( "sessionId" to sessionId.bytes, "accepted" to wasAccepted() 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 e5530d1d4..8d7d6d407 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 @@ -3,13 +3,20 @@ package org.briarproject.briar.headless.event import io.javalin.json.JavalinJson.toJson import io.javalin.websocket.WsSession import io.mockk.* +import org.briarproject.bramble.api.identity.AuthorInfo +import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED import org.briarproject.bramble.test.ImmediateExecutor +import org.briarproject.bramble.test.TestUtils.getRandomId +import org.briarproject.briar.api.client.SessionId +import org.briarproject.briar.api.introduction.IntroductionRequest +import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent import org.briarproject.briar.api.messaging.PrivateMessageHeader import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent import org.briarproject.briar.headless.ControllerTest -import org.briarproject.briar.headless.messaging.EVENT_PRIVATE_MESSAGE +import org.briarproject.briar.headless.messaging.EVENT_CONVERSATION_MESSAGE import org.briarproject.briar.headless.messaging.output import org.eclipse.jetty.websocket.api.WebSocketException +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import java.io.IOException @@ -23,7 +30,7 @@ internal class WebSocketControllerTest : ControllerTest() { private val header = PrivateMessageHeader(message.id, group.id, timestamp, true, true, true, true, emptyList()) private val event = PrivateMessageReceivedEvent(header, contact.id) - private val outputEvent = OutputEvent(EVENT_PRIVATE_MESSAGE, event.output(text)) + private val outputEvent = OutputEvent(EVENT_CONVERSATION_MESSAGE, event.output(text)) @Test fun testSendEvent() { @@ -32,7 +39,7 @@ internal class WebSocketControllerTest : ControllerTest() { every { session1.send(capture(slot)) } just Runs controller.sessions.add(session1) - controller.sendEvent(EVENT_PRIVATE_MESSAGE, event.output(text)) + controller.sendEvent(EVENT_CONVERSATION_MESSAGE, event.output(text)) assertJsonEquals(slot.captured, outputEvent) } @@ -55,13 +62,45 @@ internal class WebSocketControllerTest : ControllerTest() { controller.sessions.add(session1) controller.sessions.add(session2) - controller.sendEvent(EVENT_PRIVATE_MESSAGE, event.output(text)) + controller.sendEvent(EVENT_CONVERSATION_MESSAGE, event.output(text)) verify { session2.send(slot.captured) } } @Test - fun testOutputPrivateMessageReceivedEvent() { + fun testIntroductionRequestEvent() { + val sessionId = SessionId(getRandomId()) + val authorInfo = AuthorInfo(VERIFIED) + val introductionRequest = IntroductionRequest( + message.id, + group.id, + timestamp, + true, + true, + true, + true, + sessionId, + author, + text, + false, + authorInfo + ) + val introductionRequestEvent = + IntroductionRequestReceivedEvent(introductionRequest, contact.id) + val introductionOutputEvent = + OutputEvent(EVENT_CONVERSATION_MESSAGE, introductionRequestEvent.output()) + val slot = CapturingSlot() + + every { session1.send(capture(slot)) } just Runs + + controller.sessions.add(session1) + controller.sendEvent(EVENT_CONVERSATION_MESSAGE, introductionRequestEvent.output()) + assertJsonEquals(slot.captured, introductionOutputEvent) + assertEquals("IntroductionRequest", introductionRequestEvent.output()["type"]) + } + + @Test + fun testOutputConversationMessageReceivedEvent() { val json = """ { "type": "event", 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 0967a86f9..d27610c17 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 @@ -161,7 +161,7 @@ internal class MessagingControllerImplTest : ControllerTest() { val event = PrivateMessageReceivedEvent(header, contact.id) every { messagingManager.getMessageText(message.id) } returns text - every { webSocketController.sendEvent(EVENT_PRIVATE_MESSAGE, event.output(text)) } just runs + every { webSocketController.sendEvent(EVENT_CONVERSATION_MESSAGE, event.output(text)) } just runs controller.eventOccurred(event) }