mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
Merge pull request #494 from hjubb/refactor-sending
Fix expiration timers updates for groups
This commit is contained in:
commit
201dde7412
@ -28,12 +28,14 @@ import com.annimon.stream.Collectors;
|
|||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
import com.google.android.mms.pdu_alt.NotificationInd;
|
import com.google.android.mms.pdu_alt.NotificationInd;
|
||||||
import com.google.android.mms.pdu_alt.PduHeaders;
|
import com.google.android.mms.pdu_alt.PduHeaders;
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import net.sqlcipher.database.SQLiteDatabase;
|
import net.sqlcipher.database.SQLiteDatabase;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.session.libsession.utilities.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment;
|
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment;
|
||||||
import org.session.libsession.database.documents.IdentityKeyMismatch;
|
import org.session.libsession.database.documents.IdentityKeyMismatch;
|
||||||
@ -686,8 +688,15 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
throws MmsException
|
throws MmsException
|
||||||
{
|
{
|
||||||
if (threadId == -1) {
|
if (threadId == -1) {
|
||||||
|
if(retrieved.isGroup()) {
|
||||||
|
ByteString decodedGroupId = ((OutgoingGroupMediaMessage)retrieved).getGroupContext().getId();
|
||||||
|
String groupId = GroupUtil.doubleEncodeGroupID(decodedGroupId.toByteArray());
|
||||||
|
Recipient group = Recipient.from(context, Address.fromSerialized(groupId), false);
|
||||||
|
threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(group);
|
||||||
|
} else {
|
||||||
threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(retrieved.getRecipient());
|
threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(retrieved.getRecipient());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
long messageId = insertMessageOutbox(retrieved, threadId, false, null, serverTimestamp);
|
long messageId = insertMessageOutbox(retrieved, threadId, false, null, serverTimestamp);
|
||||||
if (messageId == -1) {
|
if (messageId == -1) {
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
|
@ -417,7 +417,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
.setName(name)
|
.setName(name)
|
||||||
.addAllMembers(members)
|
.addAllMembers(members)
|
||||||
.addAllAdmins(admins)
|
.addAllAdmins(admins)
|
||||||
val infoMessage = OutgoingGroupMediaMessage(recipient, groupContextBuilder.build(), null, sentTimestamp, 0, null, listOf(), listOf())
|
val infoMessage = OutgoingGroupMediaMessage(recipient, groupContextBuilder.build(), null, sentTimestamp, 0, false, null, listOf(), listOf())
|
||||||
val mmsDB = DatabaseFactory.getMmsDatabase(context)
|
val mmsDB = DatabaseFactory.getMmsDatabase(context)
|
||||||
val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context)
|
val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context)
|
||||||
if (mmsSmsDB.getMessageFor(sentTimestamp,userPublicKey) != null) return
|
if (mmsSmsDB.getMessageFor(sentTimestamp,userPublicKey) != null) return
|
||||||
|
@ -2,9 +2,11 @@ package org.thoughtcrime.securesms.service;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate;
|
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate;
|
||||||
|
import org.session.libsession.messaging.messages.signal.OutgoingGroupMediaMessage;
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
|
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
|
||||||
import org.session.libsession.messaging.threads.Address;
|
import org.session.libsession.messaging.threads.Address;
|
||||||
import org.session.libsession.messaging.threads.DistributionTypes;
|
import org.session.libsession.messaging.threads.DistributionTypes;
|
||||||
@ -73,32 +75,88 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setExpirationTimer(@NotNull ExpirationTimerUpdate message) {
|
public void setExpirationTimer(@NotNull ExpirationTimerUpdate message) {
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
|
||||||
|
|
||||||
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
|
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
String senderPublicKey = message.getSender();
|
String senderPublicKey = message.getSender();
|
||||||
int duration = message.getDuration();
|
|
||||||
String groupPK = message.getGroupPublicKey();
|
|
||||||
Long sentTimestamp = message.getSentTimestamp();
|
|
||||||
|
|
||||||
Optional<SignalServiceGroup> groupInfo = Optional.absent();
|
|
||||||
Address address;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (groupPK != null) {
|
|
||||||
String groupID = GroupUtil.doubleEncodeGroupID(groupPK);
|
|
||||||
groupInfo = Optional.of(new SignalServiceGroup(GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL));
|
|
||||||
address = Address.fromSerialized(groupID);
|
|
||||||
} else {
|
|
||||||
address = Address.fromSerialized((message.getSyncTarget() != null && !message.getSyncTarget().isEmpty()) ? message.getSyncTarget() : senderPublicKey);
|
|
||||||
}
|
|
||||||
Recipient recipient = Recipient.from(context, address, false);
|
|
||||||
|
|
||||||
if (recipient.isBlocked()) return;
|
|
||||||
|
|
||||||
// Notify the user
|
// Notify the user
|
||||||
if (userPublicKey.equals(senderPublicKey)) {
|
if (userPublicKey.equals(senderPublicKey)) {
|
||||||
// sender is a linked device
|
// sender is a linked device
|
||||||
|
insertOutgoingExpirationTimerMessage(message);
|
||||||
|
} else {
|
||||||
|
insertIncomingExpirationTimerMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.getId() != null) {
|
||||||
|
DatabaseFactory.getSmsDatabase(context).deleteMessage(message.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertIncomingExpirationTimerMessage(ExpirationTimerUpdate message) {
|
||||||
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
|
|
||||||
|
String senderPublicKey = message.getSender();
|
||||||
|
Long sentTimestamp = message.getSentTimestamp();
|
||||||
|
String groupId = message.getGroupPublicKey();
|
||||||
|
int duration = message.getDuration();
|
||||||
|
|
||||||
|
Optional<SignalServiceGroup> groupInfo = Optional.absent();
|
||||||
|
Address address = Address.fromSerialized((message.getSyncTarget() != null && !message.getSyncTarget().isEmpty()) ? message.getSyncTarget() : senderPublicKey);
|
||||||
|
Recipient recipient = Recipient.from(context, address, false);
|
||||||
|
|
||||||
|
// if the sender is blocked, we don't display the update, except if it's in a closed group
|
||||||
|
if (recipient.isBlocked() && groupId == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (groupId != null) {
|
||||||
|
String groupID = GroupUtil.doubleEncodeGroupID(groupId);
|
||||||
|
groupInfo = Optional.of(new SignalServiceGroup(GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL));
|
||||||
|
|
||||||
|
Address groupAddress = Address.fromSerialized(groupID);
|
||||||
|
recipient = Recipient.from(context, groupAddress, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(address, sentTimestamp, -1,
|
||||||
|
duration * 1000L, true,
|
||||||
|
false,
|
||||||
|
Optional.absent(),
|
||||||
|
groupInfo,
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent());
|
||||||
|
//insert the timer update message
|
||||||
|
database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||||
|
|
||||||
|
//set the timer to the conversation
|
||||||
|
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
||||||
|
|
||||||
|
} catch (IOException | MmsException ioe) {
|
||||||
|
Log.e("Loki", "Failed to insert expiration update message.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertOutgoingExpirationTimerMessage(ExpirationTimerUpdate message) {
|
||||||
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
|
|
||||||
|
String senderPublicKey = message.getSender();
|
||||||
|
Long sentTimestamp = message.getSentTimestamp();
|
||||||
|
String groupId = message.getGroupPublicKey();
|
||||||
|
int duration = message.getDuration();
|
||||||
|
|
||||||
|
Address address = Address.fromSerialized((message.getSyncTarget() != null && !message.getSyncTarget().isEmpty()) ? message.getSyncTarget() : senderPublicKey);
|
||||||
|
Recipient recipient = Recipient.from(context, address, false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (groupId != null) {
|
||||||
|
// conversation is a closed group
|
||||||
|
GroupContext groupContext = SignalServiceProtos.GroupContext.newBuilder()
|
||||||
|
.setId(ByteString.copyFrom(GroupUtil.getDecodedGroupIDAsData(groupId))).build();
|
||||||
|
OutgoingGroupMediaMessage infoMessage = new OutgoingGroupMediaMessage(recipient, groupContext, null, sentTimestamp, duration * 1000L, true, null, Collections.emptyList(), Collections.emptyList());
|
||||||
|
database.insertSecureDecryptedMessageOutbox(infoMessage, -1, sentTimestamp);
|
||||||
|
// we need the group ID as recipient for setExpireMessages below
|
||||||
|
recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(groupId)), false);
|
||||||
|
} else {
|
||||||
|
// conversation is a 1-1
|
||||||
OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipient,
|
OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipient,
|
||||||
null,
|
null,
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
@ -113,29 +171,12 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
|||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
Collections.emptyList());
|
Collections.emptyList());
|
||||||
database.insertSecureDecryptedMessageOutbox(mediaMessage, -1, sentTimestamp);
|
database.insertSecureDecryptedMessageOutbox(mediaMessage, -1, sentTimestamp);
|
||||||
} else {
|
|
||||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(address, sentTimestamp, -1,
|
|
||||||
duration * 1000L, true,
|
|
||||||
false,
|
|
||||||
Optional.absent(),
|
|
||||||
groupInfo,
|
|
||||||
Optional.absent(),
|
|
||||||
Optional.absent(),
|
|
||||||
Optional.absent(),
|
|
||||||
Optional.absent());
|
|
||||||
//insert the timer update message
|
|
||||||
database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the timer to the conversation
|
//set the timer to the conversation
|
||||||
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
||||||
|
|
||||||
if (message.getId() != null) {
|
} catch (MmsException | IOException ioe) {
|
||||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(message.getId());
|
|
||||||
}
|
|
||||||
} catch (MmsException e) {
|
|
||||||
Log.e("Loki", "Failed to insert expiration update message.");
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
Log.e("Loki", "Failed to insert expiration update message.");
|
Log.e("Loki", "Failed to insert expiration update message.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage {
|
|||||||
@Nullable final Attachment avatar,
|
@Nullable final Attachment avatar,
|
||||||
long sentTime,
|
long sentTime,
|
||||||
long expireIn,
|
long expireIn,
|
||||||
|
boolean expirationUpdate,
|
||||||
@Nullable QuoteModel quote,
|
@Nullable QuoteModel quote,
|
||||||
@NonNull List<Contact> contacts,
|
@NonNull List<Contact> contacts,
|
||||||
@NonNull List<LinkPreview> previews)
|
@NonNull List<LinkPreview> previews)
|
||||||
@ -65,7 +66,7 @@ public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage {
|
|||||||
super(recipient, Base64.encodeBytes(group.toByteArray()),
|
super(recipient, Base64.encodeBytes(group.toByteArray()),
|
||||||
new LinkedList<Attachment>() {{if (avatar != null) add(avatar);}},
|
new LinkedList<Attachment>() {{if (avatar != null) add(avatar);}},
|
||||||
sentTime,
|
sentTime,
|
||||||
DistributionTypes.CONVERSATION, expireIn, false, quote, contacts, previews);
|
DistributionTypes.CONVERSATION, expireIn, expirationUpdate, quote, contacts, previews);
|
||||||
|
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,11 @@ object GroupUtil {
|
|||||||
return getEncodedClosedGroupID(getEncodedClosedGroupID(Hex.fromStringCondensed(groupPublicKey)).toByteArray())
|
return getEncodedClosedGroupID(getEncodedClosedGroupID(Hex.fromStringCondensed(groupPublicKey)).toByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun doubleEncodeGroupID(groupID: ByteArray): String {
|
||||||
|
return getEncodedClosedGroupID(getEncodedClosedGroupID(groupID).toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun doubleDecodeGroupID(groupID: String): ByteArray {
|
fun doubleDecodeGroupID(groupID: String): ByteArray {
|
||||||
|
Loading…
Reference in New Issue
Block a user