Add support for sending and syncing viewed receipts behind a feature flag.

This commit is contained in:
Alex Hart
2021-04-28 16:21:34 -03:00
parent cdc7f1565e
commit ab44d608d2
16 changed files with 425 additions and 44 deletions

View File

@@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy
import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
@@ -354,6 +355,8 @@ public class SignalServiceMessageSender {
content = createMultiDeviceGroupsContent(message.getGroups().get().asStream());
} else if (message.getRead().isPresent()) {
content = createMultiDeviceReadContent(message.getRead().get());
} else if (message.getViewed().isPresent()) {
content = createMultiDeviceViewedContent(message.getViewed().get());
} else if (message.getViewOnceOpen().isPresent()) {
content = createMultiDeviceViewOnceOpenContent(message.getViewOnceOpen().get());
} else if (message.getBlockedList().isPresent()) {
@@ -964,6 +967,27 @@ public class SignalServiceMessageSender {
return container.setSyncMessage(builder).build().toByteArray();
}
private byte[] createMultiDeviceViewedContent(List<ViewedMessage> readMessages) {
Content.Builder container = Content.newBuilder();
SyncMessage.Builder builder = createSyncMessageBuilder();
for (ViewedMessage readMessage : readMessages) {
SyncMessage.Viewed.Builder viewedBuilder = SyncMessage.Viewed.newBuilder().setTimestamp(readMessage.getTimestamp());
if (readMessage.getSender().getUuid().isPresent()) {
viewedBuilder.setSenderUuid(readMessage.getSender().getUuid().get().toString());
}
if (readMessage.getSender().getNumber().isPresent()) {
viewedBuilder.setSenderE164(readMessage.getSender().getNumber().get());
}
builder.addViewed(viewedBuilder.build());
}
return container.setSyncMessage(builder).build().toByteArray();
}
private byte[] createMultiDeviceViewOnceOpenContent(ViewOnceOpenMessage readMessage) {
Content.Builder container = Content.newBuilder();
SyncMessage.Builder builder = createSyncMessageBuilder();

View File

@@ -36,6 +36,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy
import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.whispersystems.signalservice.api.payments.Money;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
@@ -465,6 +466,21 @@ public final class SignalServiceContent {
return SignalServiceSyncMessage.forRead(readMessages);
}
if (content.getViewedList().size() > 0) {
List<ViewedMessage> viewedMessages = new LinkedList<>();
for (SignalServiceProtos.SyncMessage.Viewed viewed : content.getViewedList()) {
if (SignalServiceAddress.isValidAddress(viewed.getSenderUuid(), viewed.getSenderE164())) {
SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrNull(viewed.getSenderUuid()), viewed.getSenderE164());
viewedMessages.add(new ViewedMessage(address, viewed.getTimestamp()));
} else {
Log.w(TAG, "Encountered an invalid ReadMessage! Ignoring.");
}
}
return SignalServiceSyncMessage.forViewed(viewedMessages);
}
if (content.hasViewOnceOpen()) {
if (SignalServiceAddress.isValidAddress(content.getViewOnceOpen().getSenderUuid(), content.getViewOnceOpen().getSenderE164())) {
SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrNull(content.getViewOnceOpen().getSenderUuid()), content.getViewOnceOpen().getSenderE164());

View File

@@ -28,6 +28,7 @@ public class SignalServiceSyncMessage {
private final Optional<KeysMessage> keys;
private final Optional<MessageRequestResponseMessage> messageRequestResponse;
private final Optional<OutgoingPaymentMessage> outgoingPaymentMessage;
private final Optional<List<ViewedMessage>> views;
private SignalServiceSyncMessage(Optional<SentTranscriptMessage> sent,
Optional<ContactsMessage> contacts,
@@ -42,7 +43,8 @@ public class SignalServiceSyncMessage {
Optional<FetchType> fetchType,
Optional<KeysMessage> keys,
Optional<MessageRequestResponseMessage> messageRequestResponse,
Optional<OutgoingPaymentMessage> outgoingPaymentMessage)
Optional<OutgoingPaymentMessage> outgoingPaymentMessage,
Optional<List<ViewedMessage>> views)
{
this.sent = sent;
this.contacts = contacts;
@@ -58,6 +60,7 @@ public class SignalServiceSyncMessage {
this.keys = keys;
this.messageRequestResponse = messageRequestResponse;
this.outgoingPaymentMessage = outgoingPaymentMessage;
this.views = views;
}
public static SignalServiceSyncMessage forSentTranscript(SentTranscriptMessage sent) {
@@ -74,6 +77,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -91,6 +95,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -108,6 +113,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -125,6 +131,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -142,9 +149,28 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
public static SignalServiceSyncMessage forViewed(List<ViewedMessage> views) {
return new SignalServiceSyncMessage(Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.of(views));
}
public static SignalServiceSyncMessage forViewOnceOpen(ViewOnceOpenMessage timerRead) {
return new SignalServiceSyncMessage(Optional.absent(),
Optional.absent(),
@@ -159,6 +185,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -179,6 +206,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -196,6 +224,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -213,6 +242,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -230,6 +260,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -247,6 +278,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -264,6 +296,7 @@ public class SignalServiceSyncMessage {
Optional.of(fetchType),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -281,6 +314,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.of(keys),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -298,6 +332,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.of(messageRequestResponse),
Optional.absent(),
Optional.absent());
}
@@ -315,7 +350,8 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.of(outgoingPaymentMessage));
Optional.of(outgoingPaymentMessage),
Optional.absent());
}
public static SignalServiceSyncMessage empty() {
@@ -332,6 +368,7 @@ public class SignalServiceSyncMessage {
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent(),
Optional.absent());
}
@@ -391,6 +428,10 @@ public class SignalServiceSyncMessage {
return outgoingPaymentMessage;
}
public Optional<List<ViewedMessage>> getViewed() {
return views;
}
public enum FetchType {
LOCAL_PROFILE,
STORAGE_MANIFEST

View File

@@ -0,0 +1,22 @@
package org.whispersystems.signalservice.api.messages.multidevice;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
public class ViewedMessage {
private final SignalServiceAddress sender;
private final long timestamp;
public ViewedMessage(SignalServiceAddress sender, long timestamp) {
this.sender = sender;
this.timestamp = timestamp;
}
public long getTimestamp() {
return timestamp;
}
public SignalServiceAddress getSender() {
return sender;
}
}

View File

@@ -403,6 +403,12 @@ message SyncMessage {
optional uint64 timestamp = 2;
}
message Viewed {
optional string senderE164 = 1;
optional string senderUuid = 3;
optional uint64 timestamp = 2;
}
message Configuration {
optional bool readReceipts = 1;
optional bool unidentifiedDeliveryIndicators = 2;
@@ -495,6 +501,7 @@ message SyncMessage {
optional Keys keys = 13;
optional MessageRequestResponse messageRequestResponse = 14;
optional OutgoingPayment outgoingPayment = 15;
repeated Viewed viewed = 16;
}
message AttachmentPointer {