implementation of the receiving side of Data Extraction notifications & explicit group updates notifications

This commit is contained in:
Brice-W
2021-03-16 14:56:47 +11:00
parent 1daa2a336f
commit 471e028cf3
13 changed files with 206 additions and 40 deletions

View File

@@ -11,6 +11,7 @@ import org.session.libsession.messaging.messages.visible.Attachment
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.opengroups.OpenGroup
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.threads.Address
@@ -152,4 +153,7 @@ interface StorageProtocol {
// Message Handling
/// Returns the ID of the `TSIncomingMessage` that was constructed.
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?): Long?
// Data Extraction Notification
fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, groupID: String?, sentTimestamp: Long)
}

View File

@@ -12,7 +12,7 @@ class DataExtractionNotification(): ControlMessage() {
// Kind enum
sealed class Kind {
class Screenshot() : Kind()
class MediaSaved(val timestanp: Long) : Kind()
class MediaSaved(val timestamp: Long) : Kind()
val description: String = run {
when(this) {
@@ -50,7 +50,7 @@ class DataExtractionNotification(): ControlMessage() {
val kind = kind ?: return false
return when(kind) {
is Kind.Screenshot -> true
is Kind.MediaSaved -> kind.timestanp > 0
is Kind.MediaSaved -> kind.timestamp > 0
}
}
@@ -66,7 +66,7 @@ class DataExtractionNotification(): ControlMessage() {
is Kind.Screenshot -> dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.SCREENSHOT
is Kind.MediaSaved -> {
dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.MEDIA_SAVED
dataExtractionNotification.timestamp = kind.timestanp
dataExtractionNotification.timestamp = kind.timestamp
}
}
val contentProto = SignalServiceProtos.Content.newBuilder()

View File

@@ -3,6 +3,7 @@ package org.session.libsession.messaging.messages.signal;
import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage;
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
@@ -26,9 +27,11 @@ public class IncomingMediaMessage {
private final int subscriptionId;
private final long expiresIn;
private final boolean expirationUpdate;
private final QuoteModel quote;
private final boolean unidentified;
private final DataExtractionNotificationInfoMessage dataExtractionNotification;
private final QuoteModel quote;
private final List<Attachment> attachments = new LinkedList<>();
private final List<Contact> sharedContacts = new LinkedList<>();
private final List<LinkPreview> linkPreviews = new LinkedList<>();
@@ -44,17 +47,19 @@ public class IncomingMediaMessage {
Optional<List<SignalServiceAttachment>> attachments,
Optional<QuoteModel> quote,
Optional<List<Contact>> sharedContacts,
Optional<List<LinkPreview>> linkPreviews)
Optional<List<LinkPreview>> linkPreviews,
Optional<DataExtractionNotificationInfoMessage> dataExtractionNotification)
{
this.push = true;
this.from = from;
this.sentTimeMillis = sentTimeMillis;
this.body = body.orNull();
this.subscriptionId = subscriptionId;
this.expiresIn = expiresIn;
this.expirationUpdate = expirationUpdate;
this.quote = quote.orNull();
this.unidentified = unidentified;
this.push = true;
this.from = from;
this.sentTimeMillis = sentTimeMillis;
this.body = body.orNull();
this.subscriptionId = subscriptionId;
this.expiresIn = expiresIn;
this.expirationUpdate = expirationUpdate;
this.dataExtractionNotification = dataExtractionNotification.orNull();
this.quote = quote.orNull();
this.unidentified = unidentified;
if (group.isPresent()) this.groupId = Address.fromSerialized(GroupUtil.INSTANCE.getEncodedId(group.get()));
else this.groupId = null;
@@ -70,10 +75,11 @@ public class IncomingMediaMessage {
Optional<SignalServiceGroup> group,
Optional<List<SignalServiceAttachment>> attachments,
Optional<QuoteModel> quote,
Optional<List<LinkPreview>> linkPreviews)
Optional<List<LinkPreview>> linkPreviews,
Optional<DataExtractionNotificationInfoMessage> dataExtractionNotification)
{
return new IncomingMediaMessage(from, message.getReceivedTimestamp(), -1, expiresIn, false,
false, Optional.fromNullable(message.getText()), group, attachments, quote, Optional.absent(), linkPreviews);
false, Optional.fromNullable(message.getText()), group, attachments, quote, Optional.absent(), linkPreviews, dataExtractionNotification);
}
public int getSubscriptionId() {
@@ -128,6 +134,8 @@ public class IncomingMediaMessage {
return linkPreviews;
}
public DataExtractionNotificationInfoMessage getDataExtractionNotification() { return dataExtractionNotification; }
public boolean isUnidentified() {
return unidentified;
}

View File

@@ -9,6 +9,7 @@ import org.session.libsession.messaging.messages.control.*
import org.session.libsession.messaging.messages.visible.Attachment
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
@@ -43,6 +44,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
is TypingIndicator -> handleTypingIndicator(message)
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message, proto)
is DataExtractionNotification -> handleDataExtractionNotification(message)
is ConfigurationMessage -> handleConfigurationMessage(message)
is VisibleMessage -> handleVisibleMessage(message, proto, openGroupID)
}
@@ -102,6 +104,21 @@ fun MessageReceiver.disableExpirationTimer(message: ExpirationTimerUpdate, proto
SSKEnvironment.shared.messageExpirationManager.disableExpirationTimer(id, senderPublicKey, proto)
}
// Data Extraction Notification handling
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
val storage = MessagingConfiguration.shared.storage
val senderPublicKey = message.sender!!
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIASAVED)
else -> return
}
storage.insertDataExtractionNotificationMessage(senderPublicKey, notification, message.groupPublicKey, message.sentTimestamp!!)
}
// Configuration message handling
private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMessage) {
val context = MessagingConfiguration.shared.context
val storage = MessagingConfiguration.shared.storage
@@ -239,7 +256,7 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), formationTimestamp)
// Notify the user
storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, sentTimestamp)
storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.NEW, name, members, admins, sentTimestamp)
}
storage.setProfileSharing(Address.fromSerialized(groupID), true)
// Add the group to the user's set of public keys to poll for
@@ -356,7 +373,7 @@ private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupCon
val name = kind.name
storage.updateTitle(groupID, name)
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, message.sentTimestamp!!)
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.NAME_UPDATE, name, members, admins, message.sentTimestamp!!)
}
private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupControlMessage) {
@@ -384,7 +401,7 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID, message.sentTimestamp!!)
} else {
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, message.sentTimestamp!!)
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.MEMBER_ADDED, name, members, admins, message.sentTimestamp!!)
}
if (userPublicKey in admins) {
// send current encryption key to the latest added members
@@ -445,7 +462,7 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup
}
val (contextType, signalType) =
if (senderLeft) SignalServiceProtos.GroupContext.Type.QUIT to SignalServiceGroup.Type.QUIT
else SignalServiceProtos.GroupContext.Type.UPDATE to SignalServiceGroup.Type.UPDATE
else SignalServiceProtos.GroupContext.Type.UPDATE to SignalServiceGroup.Type.MEMBER_REMOVED
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, contextType, signalType, name, members, admins, message.sentTimestamp!!)
}

View File

@@ -0,0 +1,16 @@
package org.session.libsession.messaging.sending_receiving.dataextraction
class DataExtractionNotificationInfoMessage {
enum class Kind {
SCREENSHOT,
MEDIASAVED
}
var kind: Kind? = null
constructor(kind: Kind?) {
this.kind = kind
}
}