mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-27 04:04:43 +01:00
Add support for sending and syncing viewed receipts behind a feature flag.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user