Add mentions for v2 group chats.

This commit is contained in:
Cody Henthorne
2020-08-05 16:45:52 -04:00
committed by Greyson Parrelli
parent 0bb9c1d650
commit b2d4c5d14b
90 changed files with 2279 additions and 372 deletions

View File

@@ -578,11 +578,22 @@ public class SignalServiceMessageSender {
.setText(message.getQuote().get().getText());
if (message.getQuote().get().getAuthor().getUuid().isPresent()) {
quoteBuilder = quoteBuilder.setAuthorUuid(message.getQuote().get().getAuthor().getUuid().get().toString());
quoteBuilder.setAuthorUuid(message.getQuote().get().getAuthor().getUuid().get().toString());
}
if (message.getQuote().get().getAuthor().getNumber().isPresent()) {
quoteBuilder = quoteBuilder.setAuthorE164(message.getQuote().get().getAuthor().getNumber().get());
quoteBuilder.setAuthorE164(message.getQuote().get().getAuthor().getNumber().get());
}
if (!message.getQuote().get().getMentions().isEmpty()) {
for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) {
quoteBuilder.addBodyRanges(DataMessage.BodyRange.newBuilder()
.setStart(mention.getStart())
.setLength(mention.getLength())
.setMentionUuid(mention.getUuid().toString()));
}
builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
}
for (SignalServiceDataMessage.Quote.QuotedAttachment attachment : message.getQuote().get().getAttachments()) {
@@ -626,6 +637,16 @@ public class SignalServiceMessageSender {
}
}
if (message.getMentions().isPresent()) {
for (SignalServiceDataMessage.Mention mention : message.getMentions().get()) {
builder.addBodyRanges(DataMessage.BodyRange.newBuilder()
.setStart(mention.getStart())
.setLength(mention.getLength())
.setMentionUuid(mention.getUuid().toString()));
}
builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
}
if (message.getSticker().isPresent()) {
DataMessage.Sticker.Builder stickerBuilder = DataMessage.Sticker.newBuilder();

View File

@@ -347,6 +347,7 @@ public final class SignalServiceContent {
SignalServiceDataMessage.Quote quote = createQuote(content);
List<SharedContact> sharedContacts = createSharedContacts(content);
List<SignalServiceDataMessage.Preview> previews = createPreviews(content);
List<SignalServiceDataMessage.Mention> mentions = createMentions(content);
SignalServiceDataMessage.Sticker sticker = createSticker(content);
SignalServiceDataMessage.Reaction reaction = createReaction(content);
SignalServiceDataMessage.RemoteDelete remoteDelete = createRemoteDelete(content);
@@ -381,6 +382,7 @@ public final class SignalServiceContent {
quote,
sharedContacts,
previews,
mentions,
sticker,
content.getIsViewOnce(),
reaction,
@@ -662,7 +664,8 @@ public final class SignalServiceContent {
return new SignalServiceDataMessage.Quote(content.getQuote().getId(),
address,
content.getQuote().getText(),
attachments);
attachments,
createMentions(content));
} else {
Log.w(TAG, "Quote was missing an author! Returning null.");
return null;
@@ -689,6 +692,35 @@ public final class SignalServiceContent {
return results;
}
private static List<SignalServiceDataMessage.Mention> createMentions(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
if (content.getBodyRangesCount() <= 0 || !content.hasBody()) return null;
List<SignalServiceDataMessage.Mention> mentions = new LinkedList<>();
for (SignalServiceProtos.DataMessage.BodyRange bodyRange : content.getBodyRangesList()) {
if (bodyRange.hasMentionUuid()) {
try {
validateBodyRange(content, bodyRange);
mentions.add(new SignalServiceDataMessage.Mention(UuidUtil.parseOrThrow(bodyRange.getMentionUuid()), bodyRange.getStart(), bodyRange.getLength()));
} catch (IllegalArgumentException e) {
throw new ProtocolInvalidMessageException(new InvalidMessageException(e), null, 0);
}
}
}
return mentions;
}
private static void validateBodyRange(SignalServiceProtos.DataMessage content, SignalServiceProtos.DataMessage.BodyRange bodyRange) throws ProtocolInvalidMessageException {
int incomingBodyLength = content.hasBody() ? content.getBody().length() : -1;
int start = bodyRange.hasStart() ? bodyRange.getStart() : -1;
int length = bodyRange.hasLength() ? bodyRange.getLength() : -1;
if (start < 0 || length < 0 || (start + length) > incomingBodyLength) {
throw new ProtocolInvalidMessageException(new InvalidMessageException("Incoming body range has out-of-bound range"), null, 0);
}
}
private static SignalServiceDataMessage.Sticker createSticker(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
if (!content.hasSticker() ||
!content.getSticker().hasPackId() ||

View File

@@ -14,6 +14,7 @@ import org.whispersystems.signalservice.api.util.OptionalUtil;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
/**
* Represents a decrypted Signal Service data message.
@@ -32,6 +33,7 @@ public class SignalServiceDataMessage {
private final Optional<Quote> quote;
private final Optional<List<SharedContact>> contacts;
private final Optional<List<Preview>> previews;
private final Optional<List<Mention>> mentions;
private final Optional<Sticker> sticker;
private final boolean viewOnce;
private final Optional<Reaction> reaction;
@@ -54,7 +56,7 @@ public class SignalServiceDataMessage {
String body, boolean endSession, int expiresInSeconds,
boolean expirationUpdate, byte[] profileKey, boolean profileKeyUpdate,
Quote quote, List<SharedContact> sharedContacts, List<Preview> previews,
Sticker sticker, boolean viewOnce, Reaction reaction, RemoteDelete remoteDelete)
List<Mention> mentions, Sticker sticker, boolean viewOnce, Reaction reaction, RemoteDelete remoteDelete)
{
try {
this.group = SignalServiceGroupContext.createOptional(group, groupV2);
@@ -92,6 +94,12 @@ public class SignalServiceDataMessage {
} else {
this.previews = Optional.absent();
}
if (mentions != null && !mentions.isEmpty()) {
this.mentions = Optional.of(mentions);
} else {
this.mentions = Optional.absent();
}
}
public static Builder newBuilder() {
@@ -174,6 +182,10 @@ public class SignalServiceDataMessage {
return previews;
}
public Optional<List<Mention>> getMentions() {
return mentions;
}
public Optional<Sticker> getSticker() {
return sticker;
}
@@ -195,6 +207,7 @@ public class SignalServiceDataMessage {
private List<SignalServiceAttachment> attachments = new LinkedList<>();
private List<SharedContact> sharedContacts = new LinkedList<>();
private List<Preview> previews = new LinkedList<>();
private List<Mention> mentions = new LinkedList<>();
private long timestamp;
private SignalServiceGroup group;
@@ -302,6 +315,11 @@ public class SignalServiceDataMessage {
return this;
}
public Builder withMentions(List<Mention> mentions) {
this.mentions.addAll(mentions);
return this;
}
public Builder withSticker(Sticker sticker) {
this.sticker = sticker;
return this;
@@ -327,7 +345,7 @@ public class SignalServiceDataMessage {
return new SignalServiceDataMessage(timestamp, group, groupV2, attachments, body, endSession,
expiresInSeconds, expirationUpdate, profileKey,
profileKeyUpdate, quote, sharedContacts, previews,
sticker, viewOnce, reaction, remoteDelete);
mentions, sticker, viewOnce, reaction, remoteDelete);
}
}
@@ -336,12 +354,14 @@ public class SignalServiceDataMessage {
private final SignalServiceAddress author;
private final String text;
private final List<QuotedAttachment> attachments;
private final List<Mention> mentions;
public Quote(long id, SignalServiceAddress author, String text, List<QuotedAttachment> attachments) {
public Quote(long id, SignalServiceAddress author, String text, List<QuotedAttachment> attachments, List<Mention> mentions) {
this.id = id;
this.author = author;
this.text = text;
this.attachments = attachments;
this.mentions = mentions;
}
public long getId() {
@@ -360,6 +380,10 @@ public class SignalServiceDataMessage {
return attachments;
}
public List<Mention> getMentions() {
return mentions;
}
public static class QuotedAttachment {
private final String contentType;
private final String fileName;
@@ -480,4 +504,28 @@ public class SignalServiceDataMessage {
return targetSentTimestamp;
}
}
public static class Mention {
private final UUID uuid;
private final int start;
private final int length;
public Mention(UUID uuid, int start, int length) {
this.uuid = uuid;
this.start = start;
this.length = length;
}
public UUID getUuid() {
return uuid;
}
public int getStart() {
return start;
}
public int getLength() {
return length;
}
}
}

View File

@@ -111,6 +111,15 @@ message DataMessage {
PROFILE_KEY_UPDATE = 4;
}
message BodyRange {
optional int32 start = 1;
optional int32 length = 2;
oneof associatedValue {
string mentionUuid = 3;
}
}
message Quote {
message QuotedAttachment {
optional string contentType = 1;
@@ -123,6 +132,7 @@ message DataMessage {
optional string authorUuid = 5;
optional string text = 3;
repeated QuotedAttachment attachments = 4;
repeated BodyRange bodyRanges = 6;
}
message Contact {
@@ -226,7 +236,8 @@ message DataMessage {
VIEW_ONCE_VIDEO = 3;
REACTIONS = 4;
CDN_SELECTOR_ATTACHMENTS = 5;
CURRENT = 5;
MENTIONS = 6;
CURRENT = 6;
}
optional string body = 1;
@@ -245,6 +256,7 @@ message DataMessage {
optional bool isViewOnce = 14;
optional Reaction reaction = 16;
optional Delete delete = 17;
repeated BodyRange bodyRanges = 18;
}
message NullMessage {