diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 2c750649fd..54ba2f67a2 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -76,6 +76,7 @@ import org.webrtc.voiceengine.WebRtcAudioUtils; import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI; import org.whispersystems.signalservice.loki.api.LokiLongPoller; import org.whispersystems.signalservice.loki.api.LokiP2PAPI; import org.whispersystems.signalservice.loki.api.LokiP2PAPIDelegate; @@ -423,7 +424,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc public void setUpPublicChatIfNeeded() { boolean isPublicChatSetUp = TextSecurePreferences.isPublicChatSetUp(this); if (isPublicChatSetUp) return; - GroupManager.createGroup(this, new HashSet<>(), null, "Loki Public Chat", false); + String id = "loki-group-chat-" + LokiGroupChatAPI.getPublicChatID(); + GroupManager.createGroup(id, this, new HashSet<>(), null, "Loki Public Chat", false); TextSecurePreferences.markPublicChatSetUp(this); } // endregion diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java index 4426c200d5..fa6a4a3c40 100644 --- a/src/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java @@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.lock.RegistrationLockDialog; +import org.thoughtcrime.securesms.loki.LokiGroupChatPoller; import org.thoughtcrime.securesms.notifications.MarkReadReceiver; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.permissions.Permissions; @@ -57,6 +58,7 @@ import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI; import java.util.List; @@ -104,6 +106,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit RegistrationLockDialog.showReminderIfNecessary(this); TooltipCompat.setTooltipText(searchAction, getText(R.string.SearchToolbar_search_for_conversations_contacts_and_messages)); + + LokiGroupChatPoller.poll(this, LokiGroupChatAPI.getPublicChatID()); } @Override diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java index 4010a91686..fa647eb75d 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -56,7 +56,6 @@ import org.thoughtcrime.securesms.BindableConversationItem; import org.thoughtcrime.securesms.ConfirmIdentityDialog; import org.thoughtcrime.securesms.MediaPreviewActivity; import org.thoughtcrime.securesms.MessageDetailsActivity; -import network.loki.messenger.R; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.components.AlertView; @@ -115,6 +114,8 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import network.loki.messenger.R; + /** * A view that displays an individual conversation item within a conversation * thread. Used by ComposeMessageActivity's ListActivity via a ConversationAdapter. diff --git a/src/org/thoughtcrime/securesms/groups/GroupManager.java b/src/org/thoughtcrime/securesms/groups/GroupManager.java index c342d5f9ff..f42958d9b2 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/src/org/thoughtcrime/securesms/groups/GroupManager.java @@ -41,10 +41,22 @@ public class GroupManager { @Nullable Bitmap avatar, @Nullable String name, boolean mms) + { + GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + String id = GroupUtil.getEncodedId(database.allocateGroupId(), mms); + return createGroup(id, context, members, avatar, name, mms); + } + + public static @NonNull GroupActionResult createGroup(@NonNull String id, + @NonNull Context context, + @NonNull Set members, + @Nullable Bitmap avatar, + @Nullable String name, + boolean mms) { final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms); + final String groupId = GroupUtil.getEncodedId(id.getBytes(), mms); final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); final Set
memberAddresses = getMemberAddresses(members); diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 840048e3e8..5c504176ef 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -111,6 +111,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage; @@ -240,12 +241,12 @@ public class PushDecryptJob extends BaseJob implements InjectableType { private void handleMessage(@NonNull SignalServiceEnvelope envelope, @NonNull Optional smsMessageId) { try { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context); - LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context); + GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context); + LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context); LokiPreKeyRecordDatabase lokiPreKeyRecordDatabase = DatabaseFactory.getLokiPreKeyRecordDatabase(context); - SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context)); - LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator()); + SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context)); + LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator()); // Loki - Handle session reset logic if (!envelope.isFriendRequest() && cipher.getSessionStatus(envelope) == null && envelope.isPreKeySignalMessage()) { @@ -816,7 +817,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return threadId; } - private void handleTextMessage(@NonNull SignalServiceContent content, + public void handleTextMessage(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional smsMessageId) throws StorageFailedException @@ -830,10 +831,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } Long threadId; + boolean isLokiPublicChatMessage; if (smsMessageId.isPresent() && !message.getGroupInfo().isPresent()) { + isLokiPublicChatMessage = false; threadId = database.updateBundleMessageBody(smsMessageId.get(), body).second; } else { + isLokiPublicChatMessage = new String(message.getGroupInfo().get().getGroupId()).equals("loki-group-chat-" + LokiGroupChatAPI.getPublicChatID()); notifyTypingStoppedFromIncomingMessage(recipient, content.getSender(), content.getSenderDevice()); IncomingTextMessage textMessage = new IncomingTextMessage(Address.fromSerialized(content.getSender()), @@ -852,7 +856,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (smsMessageId.isPresent()) database.deleteMessage(smsMessageId.get()); } - if (threadId != null) { + if (threadId != null && !isLokiPublicChatMessage) { MessageNotifier.updateNotification(context, threadId); } } diff --git a/src/org/thoughtcrime/securesms/loki/LokiGroupChatPoller.kt b/src/org/thoughtcrime/securesms/loki/LokiGroupChatPoller.kt new file mode 100644 index 0000000000..a474e54b49 --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/LokiGroupChatPoller.kt @@ -0,0 +1,30 @@ +package org.thoughtcrime.securesms.loki + +import android.content.Context +import android.util.Log +import org.thoughtcrime.securesms.jobs.PushDecryptJob +import org.whispersystems.libsignal.util.guava.Optional +import org.whispersystems.signalservice.api.messages.SignalServiceContent +import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage +import org.whispersystems.signalservice.api.messages.SignalServiceGroup +import org.whispersystems.signalservice.api.push.SignalServiceAddress +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI + +object LokiGroupChatPoller { + + @JvmStatic + fun poll(context: Context, groupID: Long) { + LokiGroupChatAPI.getMessages(groupID).success { messages -> + messages.map { message -> + val id = "loki-group-chat-$groupID".toByteArray() + val x1 = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, null, null, null) + val x2 = SignalServiceDataMessage(message.timestamp, x1, null, message.body) + val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})" + val x3 = SignalServiceContent(x2, senderDisplayName, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false) + PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent()) + } + }.fail { + Log.d("Loki", "Failed to get messages for group chat with ID: $groupID.") + } + } +} \ No newline at end of file