mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 18:07:41 +00:00
implementation of the receiving side of Data Extraction notifications & explicit group updates notifications
This commit is contained in:
@@ -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)
|
||||
}
|
@@ -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()
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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!!)
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user