Expire group update info and call messages

This commit is contained in:
charles 2022-12-22 10:42:09 +11:00
parent e460e086e6
commit 03c95f1ba7
8 changed files with 98 additions and 36 deletions
app/src/main/java/org/thoughtcrime/securesms
libsession/src/main/java/org/session/libsession/messaging/messages/signal

@ -1355,7 +1355,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
message.text = text message.text = text
val expiresInMillis = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L val expiresInMillis = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L
val outgoingTextMessage = OutgoingTextMessage.from(message, recipient, expiresInMillis) val expireStartedAt = if (viewModel.expirationConfiguration?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
message.sentTimestamp!!
} else 0
val outgoingTextMessage = OutgoingTextMessage.from(message, recipient, expiresInMillis, expireStartedAt)
// Clear the input bar // Clear the input bar
binding?.inputBar?.text = "" binding?.inputBar?.text = ""
binding?.inputBar?.cancelQuoteDraft() binding?.inputBar?.cancelQuoteDraft()

@ -444,6 +444,7 @@ public class SmsDatabase extends MessagingDatabase {
values.put(READ, unread ? 0 : 1); values.put(READ, unread ? 0 : 1);
values.put(SUBSCRIPTION_ID, message.getSubscriptionId()); values.put(SUBSCRIPTION_ID, message.getSubscriptionId());
values.put(EXPIRES_IN, message.getExpiresIn()); values.put(EXPIRES_IN, message.getExpiresIn());
values.put(EXPIRE_STARTED, message.getExpireStartedAt());
values.put(UNIDENTIFIED, message.isUnidentified()); values.put(UNIDENTIFIED, message.isUnidentified());
if (!TextUtils.isEmpty(message.getPseudoSubject())) if (!TextUtils.isEmpty(message.getPseudoSubject()))
@ -528,6 +529,7 @@ public class SmsDatabase extends MessagingDatabase {
contentValues.put(TYPE, type); contentValues.put(TYPE, type);
contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId()); contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId());
contentValues.put(EXPIRES_IN, message.getExpiresIn()); contentValues.put(EXPIRES_IN, message.getExpiresIn());
contentValues.put(EXPIRE_STARTED, message.getExpireStartedAt());
contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum()); contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum());
contentValues.put(READ_RECEIPT_COUNT, Stream.of(earlyReadReceipts.values()).mapToLong(Long::longValue).sum()); contentValues.put(READ_RECEIPT_COUNT, Stream.of(earlyReadReceipts.values()).mapToLong(Long::longValue).sum());

@ -159,7 +159,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
} }
} }
val expirationConfig = getExpirationConfiguration(message.threadID ?: -1) val expirationConfig = getExpirationConfiguration(message.threadID ?: -1)
val expiresIn = expirationConfig?.durationSeconds ?: 0 val expiresInMillis = (expirationConfig?.durationSeconds ?: 0) * 1000L
val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) { val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
message.sentTimestamp!! message.sentTimestamp!!
} else 0 } else 0
@ -174,7 +174,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
pointers, pointers,
quote.orNull(), quote.orNull(),
linkPreviews.orNull()?.firstOrNull(), linkPreviews.orNull()?.firstOrNull(),
expiresIn * 1000L, expiresInMillis,
expireStartedAt expireStartedAt
) )
mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!, runThreadUpdate) mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!, runThreadUpdate)
@ -183,7 +183,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
val signalServiceAttachments = attachments.mapNotNull { val signalServiceAttachments = attachments.mapNotNull {
it.toSignalPointer() it.toSignalPointer()
} }
val mediaMessage = IncomingMediaMessage.from(message, senderAddress, expiresIn * 1000L, expireStartedAt, group, signalServiceAttachments, quote, linkPreviews) val mediaMessage = IncomingMediaMessage.from(message, senderAddress, expiresInMillis, expireStartedAt, group, signalServiceAttachments, quote, linkPreviews)
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate) mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate)
} }
if (insertResult.isPresent) { if (insertResult.isPresent) {
@ -194,12 +194,12 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
val isOpenGroupInvitation = (message.openGroupInvitation != null) val isOpenGroupInvitation = (message.openGroupInvitation != null)
val insertResult = if (isUserSender || isUserBlindedSender) { val insertResult = if (isUserSender || isUserBlindedSender) {
val textMessage = if (isOpenGroupInvitation) OutgoingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, targetRecipient, message.sentTimestamp) val textMessage = if (isOpenGroupInvitation) OutgoingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, targetRecipient, message.sentTimestamp, expiresInMillis, expireStartedAt)
else OutgoingTextMessage.from(message, targetRecipient, expiresIn * 1000L) else OutgoingTextMessage.from(message, targetRecipient, expiresInMillis, expireStartedAt)
smsDatabase.insertMessageOutbox(message.threadID ?: -1, textMessage, message.sentTimestamp!!, runThreadUpdate) smsDatabase.insertMessageOutbox(message.threadID ?: -1, textMessage, message.sentTimestamp!!, runThreadUpdate)
} else { } else {
val textMessage = if (isOpenGroupInvitation) IncomingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, senderAddress, message.sentTimestamp) val textMessage = if (isOpenGroupInvitation) IncomingTextMessage.fromOpenGroupInvitation(message.openGroupInvitation, senderAddress, message.sentTimestamp, expiresInMillis, expireStartedAt)
else IncomingTextMessage.from(message, senderAddress, group, expiresIn * 1000L) else IncomingTextMessage.from(message, senderAddress, group, expiresInMillis, expireStartedAt)
val encrypted = IncomingEncryptedMessage(textMessage, textMessage.messageBody) val encrypted = IncomingEncryptedMessage(textMessage, textMessage.messageBody)
smsDatabase.insertMessageInbox(encrypted, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate) smsDatabase.insertMessageInbox(encrypted, message.receivedTimestamp ?: 0, runIncrement, runThreadUpdate)
} }
@ -479,24 +479,38 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, sentTimestamp: Long) { override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, sentTimestamp: Long) {
val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList()) val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList())
val m = IncomingTextMessage(fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true) val recipient = Recipient.from(context, fromSerialized(groupID), false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiresInMillis = (expirationConfig?.durationSeconds ?: 0) * 100L
val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
sentTimestamp
} else 0
val m = IncomingTextMessage(fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), expiresInMillis, expireStartedAt, true)
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON()
val infoMessage = IncomingGroupMessage(m, groupID, updateData, true) val infoMessage = IncomingGroupMessage(m, groupID, updateData, true)
val smsDB = DatabaseComponent.get(context).smsDatabase() val smsDB = DatabaseComponent.get(context).smsDatabase()
smsDB.insertMessageInbox(infoMessage, true, true) smsDB.insertMessageInbox(infoMessage, true, true)
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, senderPublicKey, expireStartedAt)
} }
override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) { override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) {
val userPublicKey = getUserPublicKey() val userPublicKey = getUserPublicKey()
val recipient = Recipient.from(context, fromSerialized(groupID), false) val recipient = Recipient.from(context, fromSerialized(groupID), false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiresInMillis = (expirationConfig?.durationSeconds ?: 0) * 100L
val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
sentTimestamp
} else 0
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: "" val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: ""
val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, 0, true, null, listOf(), listOf()) val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, expiresInMillis, expireStartedAt, true, null, listOf(), listOf())
val mmsDB = DatabaseComponent.get(context).mmsDatabase() val mmsDB = DatabaseComponent.get(context).mmsDatabase()
val mmsSmsDB = DatabaseComponent.get(context).mmsSmsDatabase() val mmsSmsDB = DatabaseComponent.get(context).mmsSmsDatabase()
if (mmsSmsDB.getMessageFor(sentTimestamp, userPublicKey) != null) return if (mmsSmsDB.getMessageFor(sentTimestamp, userPublicKey) != null) return
val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null, runThreadUpdate = true) val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null, runThreadUpdate = true)
mmsDB.markAsSent(infoMessageID, true) mmsDB.markAsSent(infoMessageID, true)
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, userPublicKey!!, expireStartedAt)
} }
override fun isClosedGroup(publicKey: String): Boolean { override fun isClosedGroup(publicKey: String): Boolean {
@ -844,8 +858,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
override fun insertCallMessage(senderPublicKey: String, callMessageType: CallMessageType, sentTimestamp: Long) { override fun insertCallMessage(senderPublicKey: String, callMessageType: CallMessageType, sentTimestamp: Long) {
val database = DatabaseComponent.get(context).smsDatabase() val database = DatabaseComponent.get(context).smsDatabase()
val address = fromSerialized(senderPublicKey) val address = fromSerialized(senderPublicKey)
val callMessage = IncomingTextMessage.fromCallInfo(callMessageType, address, Optional.absent(), sentTimestamp) val recipient = Recipient.from(context, address, false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiresInMillis = (expirationConfig?.durationSeconds ?: 0) * 100L
val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
sentTimestamp
} else 0
val callMessage = IncomingTextMessage.fromCallInfo(callMessageType, address, Optional.absent(), sentTimestamp, expiresInMillis, expireStartedAt)
database.insertCallMessage(callMessage) database.insertCallMessage(callMessage)
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, senderPublicKey, expireStartedAt)
} }
override fun conversationHasOutgoing(userPublicKey: String): Boolean { override fun conversationHasOutgoing(userPublicKey: String): Boolean {

@ -31,8 +31,10 @@ import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage;
import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.session.libsession.snode.SnodeAPI;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.protos.SignalServiceProtos;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
@ -83,10 +85,11 @@ public class AndroidAutoReplyReceiver extends BroadcastReceiver {
VisibleMessage message = new VisibleMessage(); VisibleMessage message = new VisibleMessage();
message.setText(responseText.toString()); message.setText(responseText.toString());
message.setSentTimestamp(System.currentTimeMillis()); message.setSentTimestamp(System.currentTimeMillis() + SnodeAPI.INSTANCE.getClockOffset());
MessageSender.send(message, recipient.getAddress()); MessageSender.send(message, recipient.getAddress());
ExpirationConfiguration config = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId); ExpirationConfiguration config = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId);
long expiresInMillis = config == null ? 0 : config.getDurationSeconds() * 1000L; long expiresInMillis = config == null ? 0 : config.getDurationSeconds() * 1000L;
long expireStartedAt = config.getExpirationType() == SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND ? message.getSentTimestamp() : 0L;
if (recipient.isGroupRecipient()) { if (recipient.isGroupRecipient()) {
Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message"); Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message");
@ -98,7 +101,7 @@ public class AndroidAutoReplyReceiver extends BroadcastReceiver {
} }
} else { } else {
Log.w("AndroidAutoReplyReceiver", "Sending regular message "); Log.w("AndroidAutoReplyReceiver", "Sending regular message ");
OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient, expiresInMillis); OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient, expiresInMillis, expireStartedAt);
DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(replyThreadId, reply, false, System.currentTimeMillis(), null, true); DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(replyThreadId, reply, false, System.currentTimeMillis(), null, true);
} }

@ -31,8 +31,10 @@ import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage;
import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.session.libsession.snode.SnodeAPI;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
@ -77,10 +79,11 @@ public class RemoteReplyReceiver extends BroadcastReceiver {
ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase(); ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase();
long threadId = threadDatabase.getOrCreateThreadIdFor(recipient); long threadId = threadDatabase.getOrCreateThreadIdFor(recipient);
VisibleMessage message = new VisibleMessage(); VisibleMessage message = new VisibleMessage();
message.setSentTimestamp(System.currentTimeMillis()); message.setSentTimestamp(System.currentTimeMillis() + SnodeAPI.INSTANCE.getClockOffset());
message.setText(responseText.toString()); message.setText(responseText.toString());
ExpirationConfiguration config = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId); ExpirationConfiguration config = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId);
long expiresInMillis = config == null ? 0 : config.getDurationSeconds() * 1000L; long expiresInMillis = config == null ? 0 : config.getDurationSeconds() * 1000L;
long expireStartedAt = config.getExpirationType() == ExpirationType.DELETE_AFTER_SEND ? message.getSentTimestamp() : 0L;
switch (replyMethod) { switch (replyMethod) {
case GroupMessage: { case GroupMessage: {
OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null, expiresInMillis, 0); OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null, expiresInMillis, 0);
@ -93,7 +96,7 @@ public class RemoteReplyReceiver extends BroadcastReceiver {
break; break;
} }
case SecureMessage: { case SecureMessage: {
OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient, expiresInMillis); OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient, expiresInMillis, expireStartedAt);
DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(threadId, reply, false, System.currentTimeMillis(), null, true); DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(threadId, reply, false, System.currentTimeMillis(), null, true);
MessageSender.send(message, address); MessageSender.send(message, address);
break; break;

@ -14,8 +14,10 @@ import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.toHexString import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.database.DraftDatabase import org.thoughtcrime.securesms.database.DraftDatabase
import org.thoughtcrime.securesms.database.ExpirationConfigurationDatabase
import org.thoughtcrime.securesms.database.LokiMessageDatabase import org.thoughtcrime.securesms.database.LokiMessageDatabase
import org.thoughtcrime.securesms.database.LokiThreadDatabase import org.thoughtcrime.securesms.database.LokiThreadDatabase
import org.thoughtcrime.securesms.database.MmsDatabase import org.thoughtcrime.securesms.database.MmsDatabase
@ -82,7 +84,8 @@ class DefaultConversationRepository @Inject constructor(
private val mmsSmsDb: MmsSmsDatabase, private val mmsSmsDb: MmsSmsDatabase,
private val recipientDb: RecipientDatabase, private val recipientDb: RecipientDatabase,
private val lokiMessageDb: LokiMessageDatabase, private val lokiMessageDb: LokiMessageDatabase,
private val sessionJobDb: SessionJobDatabase private val sessionJobDb: SessionJobDatabase,
private val configDb: ExpirationConfigurationDatabase
) : ConversationRepository { ) : ConversationRepository {
override fun maybeGetRecipientForThreadId(threadId: Long): Recipient? { override fun maybeGetRecipientForThreadId(threadId: Long): Recipient? {
@ -111,10 +114,17 @@ class DefaultConversationRepository @Inject constructor(
openGroupInvitation.name = openGroup.name openGroupInvitation.name = openGroup.name
openGroupInvitation.url = openGroup.joinURL openGroupInvitation.url = openGroup.joinURL
message.openGroupInvitation = openGroupInvitation message.openGroupInvitation = openGroupInvitation
val expirationConfig = configDb.getExpirationConfiguration(threadId)
val expiresInMillis = (expirationConfig?.durationSeconds ?: 0) * 1000L
val expireStartedAt = if (expirationConfig?.expirationType == SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND) {
message.sentTimestamp!!
} else 0
val outgoingTextMessage = OutgoingTextMessage.fromOpenGroupInvitation( val outgoingTextMessage = OutgoingTextMessage.fromOpenGroupInvitation(
openGroupInvitation, openGroupInvitation,
contact, contact,
message.sentTimestamp message.sentTimestamp,
expiresInMillis,
expireStartedAt
) )
smsDb.insertMessageOutbox(-1, outgoingTextMessage, message.sentTimestamp!!, true) smsDb.insertMessageOutbox(-1, outgoingTextMessage, message.sentTimestamp!!, true)
MessageSender.send(message, contact.address) MessageSender.send(message, contact.address)

@ -41,6 +41,7 @@ public class IncomingTextMessage implements Parcelable {
private final boolean push; private final boolean push;
private final int subscriptionId; private final int subscriptionId;
private final long expiresInMillis; private final long expiresInMillis;
private final long expireStartedAt;
private final boolean unidentified; private final boolean unidentified;
private final int callType; private final int callType;
@ -48,19 +49,19 @@ public class IncomingTextMessage implements Parcelable {
public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis, public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis,
String encodedBody, Optional<SignalServiceGroup> group, String encodedBody, Optional<SignalServiceGroup> group,
long expiresInMillis, boolean unidentified) { long expiresInMillis, long expireStartedAt, boolean unidentified) {
this(sender, senderDeviceId, sentTimestampMillis, encodedBody, group, expiresInMillis, unidentified, -1); this(sender, senderDeviceId, sentTimestampMillis, encodedBody, group, expiresInMillis, expireStartedAt, unidentified, -1);
} }
public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis, public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis,
String encodedBody, Optional<SignalServiceGroup> group, String encodedBody, Optional<SignalServiceGroup> group,
long expiresInMillis, boolean unidentified, int callType) { long expiresInMillis, long expireStartedAt, boolean unidentified, int callType) {
this(sender, senderDeviceId, sentTimestampMillis, encodedBody, group, expiresInMillis, unidentified, callType, true); this(sender, senderDeviceId, sentTimestampMillis, encodedBody, group, expiresInMillis, expireStartedAt, unidentified, callType, true);
} }
public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis, public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis,
String encodedBody, Optional<SignalServiceGroup> group, String encodedBody, Optional<SignalServiceGroup> group,
long expiresInMillis, boolean unidentified, int callType, boolean isPush) { long expiresInMillis, long expireStartedAt, boolean unidentified, int callType, boolean isPush) {
this.message = encodedBody; this.message = encodedBody;
this.sender = sender; this.sender = sender;
this.senderDeviceId = senderDeviceId; this.senderDeviceId = senderDeviceId;
@ -72,6 +73,7 @@ public class IncomingTextMessage implements Parcelable {
this.push = isPush; this.push = isPush;
this.subscriptionId = -1; this.subscriptionId = -1;
this.expiresInMillis = expiresInMillis; this.expiresInMillis = expiresInMillis;
this.expireStartedAt = expireStartedAt;
this.unidentified = unidentified; this.unidentified = unidentified;
this.callType = callType; this.callType = callType;
@ -95,6 +97,7 @@ public class IncomingTextMessage implements Parcelable {
this.push = (in.readInt() == 1); this.push = (in.readInt() == 1);
this.subscriptionId = in.readInt(); this.subscriptionId = in.readInt();
this.expiresInMillis = in.readLong(); this.expiresInMillis = in.readLong();
this.expireStartedAt = in.readLong();
this.unidentified = in.readInt() == 1; this.unidentified = in.readInt() == 1;
this.isOpenGroupInvitation = in.readInt() == 1; this.isOpenGroupInvitation = in.readInt() == 1;
this.callType = in.readInt(); this.callType = in.readInt();
@ -113,6 +116,7 @@ public class IncomingTextMessage implements Parcelable {
this.push = base.isPush(); this.push = base.isPush();
this.subscriptionId = base.getSubscriptionId(); this.subscriptionId = base.getSubscriptionId();
this.expiresInMillis = base.getExpiresIn(); this.expiresInMillis = base.getExpiresIn();
this.expireStartedAt = base.getExpireStartedAt();
this.unidentified = base.isUnidentified(); this.unidentified = base.isUnidentified();
this.isOpenGroupInvitation = base.isOpenGroupInvitation(); this.isOpenGroupInvitation = base.isOpenGroupInvitation();
this.callType = base.callType; this.callType = base.callType;
@ -121,19 +125,23 @@ public class IncomingTextMessage implements Parcelable {
public static IncomingTextMessage from(VisibleMessage message, public static IncomingTextMessage from(VisibleMessage message,
Address sender, Address sender,
Optional<SignalServiceGroup> group, Optional<SignalServiceGroup> group,
long expiresInMillis) long expiresInMillis,
long expireStartedAt)
{ {
return new IncomingTextMessage(sender, 1, message.getSentTimestamp(), message.getText(), group, expiresInMillis, false); return new IncomingTextMessage(sender, 1, message.getSentTimestamp(), message.getText(), group, expiresInMillis, expireStartedAt, false);
} }
public static IncomingTextMessage fromOpenGroupInvitation(OpenGroupInvitation openGroupInvitation, Address sender, Long sentTimestamp) public static IncomingTextMessage fromOpenGroupInvitation(OpenGroupInvitation openGroupInvitation,
{ Address sender,
Long sentTimestamp,
long expiresInMillis,
long expireStartedAt) {
String url = openGroupInvitation.getUrl(); String url = openGroupInvitation.getUrl();
String name = openGroupInvitation.getName(); String name = openGroupInvitation.getName();
if (url == null || name == null) { return null; } if (url == null || name == null) { return null; }
// FIXME: Doing toJSON() to get the body here is weird // FIXME: Doing toJSON() to get the body here is weird
String body = UpdateMessageData.Companion.buildOpenGroupInvitation(url, name).toJSON(); String body = UpdateMessageData.Companion.buildOpenGroupInvitation(url, name).toJSON();
IncomingTextMessage incomingTextMessage = new IncomingTextMessage(sender, 1, sentTimestamp, body, Optional.absent(), 0, false); IncomingTextMessage incomingTextMessage = new IncomingTextMessage(sender, 1, sentTimestamp, body, Optional.absent(), expiresInMillis, expireStartedAt, false);
incomingTextMessage.isOpenGroupInvitation = true; incomingTextMessage.isOpenGroupInvitation = true;
return incomingTextMessage; return incomingTextMessage;
} }
@ -141,8 +149,10 @@ public class IncomingTextMessage implements Parcelable {
public static IncomingTextMessage fromCallInfo(CallMessageType callMessageType, public static IncomingTextMessage fromCallInfo(CallMessageType callMessageType,
Address sender, Address sender,
Optional<SignalServiceGroup> group, Optional<SignalServiceGroup> group,
long sentTimestamp) { long sentTimestamp,
return new IncomingTextMessage(sender, 1, sentTimestamp, null, group, 0, false, callMessageType.ordinal(), false); long expiresInMillis,
long expireStartedAt) {
return new IncomingTextMessage(sender, 1, sentTimestamp, null, group, expiresInMillis, expireStartedAt, false, callMessageType.ordinal(), false);
} }
public int getSubscriptionId() { public int getSubscriptionId() {
@ -153,6 +163,10 @@ public class IncomingTextMessage implements Parcelable {
return expiresInMillis; return expiresInMillis;
} }
public long getExpireStartedAt() {
return expireStartedAt;
}
public long getSentTimestampMillis() { public long getSentTimestampMillis() {
return sentTimestampMillis; return sentTimestampMillis;
} }

@ -1,6 +1,5 @@
package org.session.libsession.messaging.messages.signal; package org.session.libsession.messaging.messages.signal;
import org.session.libsession.messaging.messages.ExpirationConfiguration;
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation; import org.session.libsession.messaging.messages.visible.OpenGroupInvitation;
import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
@ -11,28 +10,30 @@ public class OutgoingTextMessage {
private final String message; private final String message;
private final int subscriptionId; private final int subscriptionId;
private final long expiresIn; private final long expiresIn;
private final long expireStartedAt;
private final long sentTimestampMillis; private final long sentTimestampMillis;
private boolean isOpenGroupInvitation = false; private boolean isOpenGroupInvitation = false;
public OutgoingTextMessage(Recipient recipient, String message, long expiresIn, int subscriptionId, long sentTimestampMillis) { public OutgoingTextMessage(Recipient recipient, String message, long expiresIn, long expireStartedAt, int subscriptionId, long sentTimestampMillis) {
this.recipient = recipient; this.recipient = recipient;
this.message = message; this.message = message;
this.expiresIn = expiresIn; this.expiresIn = expiresIn;
this.expireStartedAt= expireStartedAt;
this.subscriptionId = subscriptionId; this.subscriptionId = subscriptionId;
this.sentTimestampMillis = sentTimestampMillis; this.sentTimestampMillis = sentTimestampMillis;
} }
public static OutgoingTextMessage from(VisibleMessage message, Recipient recipient, long expiresInMillis) { public static OutgoingTextMessage from(VisibleMessage message, Recipient recipient, long expiresInMillis, long expireStartedAt) {
return new OutgoingTextMessage(recipient, message.getText(), expiresInMillis, -1, message.getSentTimestamp()); return new OutgoingTextMessage(recipient, message.getText(), expiresInMillis, expireStartedAt, -1, message.getSentTimestamp());
} }
public static OutgoingTextMessage fromOpenGroupInvitation(OpenGroupInvitation openGroupInvitation, Recipient recipient, Long sentTimestamp) { public static OutgoingTextMessage fromOpenGroupInvitation(OpenGroupInvitation openGroupInvitation, Recipient recipient, Long sentTimestamp, long expiresInMillis, long expireStartedAt) {
String url = openGroupInvitation.getUrl(); String url = openGroupInvitation.getUrl();
String name = openGroupInvitation.getName(); String name = openGroupInvitation.getName();
if (url == null || name == null) { return null; } if (url == null || name == null) { return null; }
// FIXME: Doing toJSON() to get the body here is weird // FIXME: Doing toJSON() to get the body here is weird
String body = UpdateMessageData.Companion.buildOpenGroupInvitation(url, name).toJSON(); String body = UpdateMessageData.Companion.buildOpenGroupInvitation(url, name).toJSON();
OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, body, 0, -1, sentTimestamp); OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, body, expiresInMillis, expireStartedAt, -1, sentTimestamp);
outgoingTextMessage.isOpenGroupInvitation = true; outgoingTextMessage.isOpenGroupInvitation = true;
return outgoingTextMessage; return outgoingTextMessage;
} }
@ -41,6 +42,10 @@ public class OutgoingTextMessage {
return expiresIn; return expiresIn;
} }
public long getExpireStartedAt() {
return expireStartedAt;
}
public int getSubscriptionId() { public int getSubscriptionId() {
return subscriptionId; return subscriptionId;
} }