mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-16 02:01:55 +00:00
GV2 group context proto.
This commit is contained in:
committed by
Greyson Parrelli
parent
20d1a93b09
commit
640c82d517
@@ -27,6 +27,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPoin
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupContext;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.AnswerMessage;
|
||||
@@ -64,6 +66,7 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.CallMe
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.NullMessage;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.ReceiptMessage;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMessage;
|
||||
@@ -451,8 +454,15 @@ public class SignalServiceMessageSender {
|
||||
builder.setBody(message.getBody().get());
|
||||
}
|
||||
|
||||
if (message.getGroupInfo().isPresent()) {
|
||||
builder.setGroup(createGroupContent(message.getGroupInfo().get()));
|
||||
if (message.getGroupContext().isPresent()) {
|
||||
SignalServiceGroupContext groupContext = message.getGroupContext().get();
|
||||
if (groupContext.getGroupV1().isPresent()) {
|
||||
builder.setGroup(createGroupContent(groupContext.getGroupV1().get()));
|
||||
}
|
||||
|
||||
if (groupContext.getGroupV2().isPresent()) {
|
||||
builder.setGroupV2(createGroupContent(groupContext.getGroupV2().get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (message.isEndSession()) {
|
||||
@@ -966,6 +976,19 @@ public class SignalServiceMessageSender {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static GroupContextV2 createGroupContent(SignalServiceGroupV2 group) {
|
||||
GroupContextV2.Builder builder = GroupContextV2.newBuilder()
|
||||
.setMasterKey(ByteString.copyFrom(group.getMasterKey().serialize()))
|
||||
.setRevision(group.getRevision());
|
||||
|
||||
byte[] signedGroupChange = group.getSignedGroupChange();
|
||||
if (signedGroupChange != null) {
|
||||
builder.setGroupChange(ByteString.copyFrom(signedGroupChange));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private List<DataMessage.Contact> createSharedContactContent(List<SharedContact> contacts) throws IOException {
|
||||
List<DataMessage.Contact> results = new LinkedList<>();
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import org.signal.libsignal.metadata.ProtocolInvalidKeyException;
|
||||
import org.signal.libsignal.metadata.ProtocolInvalidMessageException;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
@@ -253,7 +255,17 @@ public final class SignalServiceContent {
|
||||
private static SignalServiceDataMessage createSignalServiceMessage(SignalServiceMetadata metadata, SignalServiceProtos.DataMessage content)
|
||||
throws ProtocolInvalidMessageException, UnsupportedDataMessageException
|
||||
{
|
||||
SignalServiceGroup groupInfo = createGroupInfo(content);
|
||||
SignalServiceGroup groupInfoV1 = createGroupV1Info(content);
|
||||
SignalServiceGroupV2 groupInfoV2 = createGroupV2Info(content);
|
||||
Optional<SignalServiceGroupContext> groupContext;
|
||||
|
||||
try {
|
||||
groupContext = SignalServiceGroupContext.createOptional(groupInfoV1, groupInfoV2);
|
||||
} catch (InvalidMessageException e) {
|
||||
throw new ProtocolInvalidMessageException(e, null, 0);
|
||||
}
|
||||
|
||||
|
||||
List<SignalServiceAttachment> attachments = new LinkedList<>();
|
||||
boolean endSession = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.END_SESSION_VALUE ) != 0);
|
||||
boolean expirationUpdate = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0);
|
||||
@@ -269,7 +281,7 @@ public final class SignalServiceContent {
|
||||
content.getRequiredProtocolVersion(),
|
||||
metadata.getSender().getIdentifier(),
|
||||
metadata.getSenderDevice(),
|
||||
Optional.fromNullable(groupInfo));
|
||||
groupContext);
|
||||
}
|
||||
|
||||
for (SignalServiceProtos.AttachmentPointer pointer : content.getAttachmentsList()) {
|
||||
@@ -283,7 +295,7 @@ public final class SignalServiceContent {
|
||||
}
|
||||
|
||||
return new SignalServiceDataMessage(metadata.getTimestamp(),
|
||||
groupInfo,
|
||||
groupInfoV1, groupInfoV2,
|
||||
attachments,
|
||||
content.getBody(),
|
||||
endSession,
|
||||
@@ -310,7 +322,7 @@ public final class SignalServiceContent {
|
||||
? Optional.of(new SignalServiceAddress(UuidUtil.parseOrNull(sentContent.getDestinationUuid()), sentContent.getDestinationE164()))
|
||||
: Optional.<SignalServiceAddress>absent();
|
||||
|
||||
if (!address.isPresent() && !dataMessage.getGroupInfo().isPresent()) {
|
||||
if (!address.isPresent() && !dataMessage.getGroupContext().isPresent()) {
|
||||
throw new ProtocolInvalidMessageException(new InvalidMessageException("SyncMessage missing both destination and group ID!"), null, 0);
|
||||
}
|
||||
|
||||
@@ -739,7 +751,7 @@ public final class SignalServiceContent {
|
||||
|
||||
}
|
||||
|
||||
private static SignalServiceGroup createGroupInfo(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
|
||||
private static SignalServiceGroup createGroupV1Info(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
|
||||
if (!content.hasGroup()) return null;
|
||||
|
||||
SignalServiceGroup.Type type;
|
||||
@@ -799,4 +811,30 @@ public final class SignalServiceContent {
|
||||
|
||||
return new SignalServiceGroup(content.getGroup().getId().toByteArray());
|
||||
}
|
||||
|
||||
private static SignalServiceGroupV2 createGroupV2Info(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
|
||||
if (!content.hasGroupV2()) return null;
|
||||
|
||||
SignalServiceProtos.GroupContextV2 groupV2 = content.getGroupV2();
|
||||
if (!groupV2.hasMasterKey()) {
|
||||
throw new ProtocolInvalidMessageException(new InvalidMessageException("No GV2 master key on message"), null, 0);
|
||||
}
|
||||
if (!groupV2.hasRevision()) {
|
||||
throw new ProtocolInvalidMessageException(new InvalidMessageException("No GV2 revision on message"), null, 0);
|
||||
}
|
||||
|
||||
SignalServiceGroupV2.Builder builder;
|
||||
try {
|
||||
builder = SignalServiceGroupV2.newBuilder(new GroupMasterKey(groupV2.getMasterKey().toByteArray()))
|
||||
.withRevision(groupV2.getRevision());
|
||||
} catch (InvalidInputException e) {
|
||||
throw new ProtocolInvalidMessageException(new InvalidMessageException(e), null, 0);
|
||||
}
|
||||
|
||||
if (groupV2.hasGroupChange()) {
|
||||
builder.withSignedGroupChange(groupV2.getGroupChange().toByteArray());
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package org.whispersystems.signalservice.api.messages;
|
||||
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
@@ -21,7 +22,7 @@ public class SignalServiceDataMessage {
|
||||
private final long timestamp;
|
||||
private final Optional<List<SignalServiceAttachment>> attachments;
|
||||
private final Optional<String> body;
|
||||
private final Optional<SignalServiceGroup> group;
|
||||
private final Optional<SignalServiceGroupContext> group;
|
||||
private final Optional<byte[]> profileKey;
|
||||
private final boolean endSession;
|
||||
private final boolean expirationUpdate;
|
||||
@@ -34,101 +35,33 @@ public class SignalServiceDataMessage {
|
||||
private final boolean viewOnce;
|
||||
private final Optional<Reaction> reaction;
|
||||
|
||||
/**
|
||||
* Construct a SignalServiceDataMessage with a body and no attachments.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param body The message contents.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, String body) {
|
||||
this(timestamp, body, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an expiring SignalServiceDataMessage with a body and no attachments.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param body The message contents.
|
||||
* @param expiresInSeconds The number of seconds in which the message should expire after having been seen.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, String body, int expiresInSeconds) {
|
||||
this(timestamp, (List<SignalServiceAttachment>)null, body, expiresInSeconds);
|
||||
}
|
||||
|
||||
|
||||
public SignalServiceDataMessage(final long timestamp, final SignalServiceAttachment attachment, final String body) {
|
||||
this(timestamp, new LinkedList<SignalServiceAttachment>() {{add(attachment);}}, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SignalServiceDataMessage with a body and list of attachments.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param attachments The attachments.
|
||||
* @param body The message contents.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, List<SignalServiceAttachment> attachments, String body) {
|
||||
this(timestamp, attachments, body, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an expiring SignalServiceDataMessage with a body and list of attachments.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param attachments The attachments.
|
||||
* @param body The message contents.
|
||||
* @param expiresInSeconds The number of seconds in which the message should expire after having been seen.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, List<SignalServiceAttachment> attachments, String body, int expiresInSeconds) {
|
||||
this(timestamp, null, attachments, body, expiresInSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SignalServiceDataMessage group message with attachments and body.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param group The group information.
|
||||
* @param attachments The attachments.
|
||||
* @param body The message contents.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, SignalServiceGroup group, List<SignalServiceAttachment> attachments, String body) {
|
||||
this(timestamp, group, attachments, body, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an expiring SignalServiceDataMessage group message with attachments and body.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param group The group information.
|
||||
* @param attachments The attachments.
|
||||
* @param body The message contents.
|
||||
* @param expiresInSeconds The number of seconds in which a message should disappear after having been seen.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, SignalServiceGroup group, List<SignalServiceAttachment> attachments, String body, int expiresInSeconds) {
|
||||
this(timestamp, group, attachments, body, false, expiresInSeconds, false, null, false, null, null, null, null, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SignalServiceDataMessage.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param group The group information (or null if none).
|
||||
* @param groupV2 The group information (or null if none).
|
||||
* @param attachments The attachments (or null if none).
|
||||
* @param body The message contents.
|
||||
* @param endSession Flag indicating whether this message should close a session.
|
||||
* @param expiresInSeconds Number of seconds in which the message should disappear after being seen.
|
||||
*/
|
||||
public SignalServiceDataMessage(long timestamp, SignalServiceGroup group,
|
||||
List<SignalServiceAttachment> attachments,
|
||||
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)
|
||||
SignalServiceDataMessage(long timestamp,
|
||||
SignalServiceGroup group, SignalServiceGroupV2 groupV2,
|
||||
List<SignalServiceAttachment> attachments,
|
||||
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)
|
||||
{
|
||||
try {
|
||||
this.group = SignalServiceGroupContext.createOptional(group, groupV2);
|
||||
} catch (InvalidMessageException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
this.timestamp = timestamp;
|
||||
this.body = Optional.fromNullable(body);
|
||||
this.group = Optional.fromNullable(group);
|
||||
this.endSession = endSession;
|
||||
this.expiresInSeconds = expiresInSeconds;
|
||||
this.expirationUpdate = expirationUpdate;
|
||||
@@ -184,9 +117,9 @@ public class SignalServiceDataMessage {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The message group info (if any).
|
||||
* @return The message group context (if any).
|
||||
*/
|
||||
public Optional<SignalServiceGroup> getGroupInfo() {
|
||||
public Optional<SignalServiceGroupContext> getGroupContext() {
|
||||
return group;
|
||||
}
|
||||
|
||||
@@ -202,8 +135,10 @@ public class SignalServiceDataMessage {
|
||||
return profileKeyUpdate;
|
||||
}
|
||||
|
||||
public boolean isGroupUpdate() {
|
||||
return group.isPresent() && group.get().getType() != SignalServiceGroup.Type.DELIVER;
|
||||
public boolean isGroupV1Update() {
|
||||
return group.isPresent() &&
|
||||
group.get().getGroupV1().isPresent() &&
|
||||
group.get().getGroupV1().get().getType() != SignalServiceGroup.Type.DELIVER;
|
||||
}
|
||||
|
||||
public int getExpiresInSeconds() {
|
||||
@@ -244,18 +179,19 @@ public class SignalServiceDataMessage {
|
||||
private List<SharedContact> sharedContacts = new LinkedList<>();
|
||||
private List<Preview> previews = new LinkedList<>();
|
||||
|
||||
private long timestamp;
|
||||
private SignalServiceGroup group;
|
||||
private String body;
|
||||
private boolean endSession;
|
||||
private int expiresInSeconds;
|
||||
private boolean expirationUpdate;
|
||||
private byte[] profileKey;
|
||||
private boolean profileKeyUpdate;
|
||||
private Quote quote;
|
||||
private Sticker sticker;
|
||||
private boolean viewOnce;
|
||||
private Reaction reaction;
|
||||
private long timestamp;
|
||||
private SignalServiceGroup group;
|
||||
private SignalServiceGroupV2 groupV2;
|
||||
private String body;
|
||||
private boolean endSession;
|
||||
private int expiresInSeconds;
|
||||
private boolean expirationUpdate;
|
||||
private byte[] profileKey;
|
||||
private boolean profileKeyUpdate;
|
||||
private Quote quote;
|
||||
private Sticker sticker;
|
||||
private boolean viewOnce;
|
||||
private Reaction reaction;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
@@ -265,10 +201,21 @@ public class SignalServiceDataMessage {
|
||||
}
|
||||
|
||||
public Builder asGroupMessage(SignalServiceGroup group) {
|
||||
if (this.groupV2 != null) {
|
||||
throw new AssertionError("Can not contain both V1 and V2 group contexts.");
|
||||
}
|
||||
this.group = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder asGroupMessage(SignalServiceGroupV2 group) {
|
||||
if (this.group != null) {
|
||||
throw new AssertionError("Can not contain both V1 and V2 group contexts.");
|
||||
}
|
||||
this.groupV2 = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAttachment(SignalServiceAttachment attachment) {
|
||||
this.attachments.add(attachment);
|
||||
return this;
|
||||
@@ -354,7 +301,7 @@ public class SignalServiceDataMessage {
|
||||
|
||||
public SignalServiceDataMessage build() {
|
||||
if (timestamp == 0) timestamp = System.currentTimeMillis();
|
||||
return new SignalServiceDataMessage(timestamp, group, attachments, body, endSession,
|
||||
return new SignalServiceDataMessage(timestamp, group, groupV2, attachments, body, endSession,
|
||||
expiresInSeconds, expirationUpdate, profileKey,
|
||||
profileKeyUpdate, quote, sharedContacts, previews,
|
||||
sticker, viewOnce, reaction);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Open Whisper Systems
|
||||
*
|
||||
* Licensed according to the LICENSE file in this repository.
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.whispersystems.signalservice.api.messages;
|
||||
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
public final class SignalServiceGroupContext {
|
||||
|
||||
private final Optional<SignalServiceGroup> groupV1;
|
||||
private final Optional<SignalServiceGroupV2> groupV2;
|
||||
|
||||
private SignalServiceGroupContext(SignalServiceGroup groupV1) {
|
||||
this.groupV1 = Optional.of(groupV1);
|
||||
this.groupV2 = Optional.absent();
|
||||
}
|
||||
|
||||
private SignalServiceGroupContext(SignalServiceGroupV2 groupV2) {
|
||||
this.groupV1 = Optional.absent();
|
||||
this.groupV2 = Optional.of(groupV2);
|
||||
}
|
||||
|
||||
public Optional<SignalServiceGroup> getGroupV1() {
|
||||
return groupV1;
|
||||
}
|
||||
|
||||
public Optional<SignalServiceGroupV2> getGroupV2() {
|
||||
return groupV2;
|
||||
}
|
||||
|
||||
static Optional<SignalServiceGroupContext> createOptional(SignalServiceGroup groupV1, SignalServiceGroupV2 groupV2)
|
||||
throws InvalidMessageException
|
||||
{
|
||||
return Optional.fromNullable(create(groupV1, groupV2));
|
||||
}
|
||||
|
||||
public static SignalServiceGroupContext create(SignalServiceGroup groupV1, SignalServiceGroupV2 groupV2)
|
||||
throws InvalidMessageException
|
||||
{
|
||||
if (groupV1 == null && groupV2 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (groupV1 != null && groupV2 != null) {
|
||||
throw new InvalidMessageException("Message cannot have both V1 and V2 group contexts.");
|
||||
}
|
||||
|
||||
if (groupV1 != null) {
|
||||
return new SignalServiceGroupContext(groupV1);
|
||||
} else {
|
||||
return new SignalServiceGroupContext(groupV2);
|
||||
}
|
||||
}
|
||||
|
||||
public SignalServiceGroup.Type getGroupV1Type() {
|
||||
if (groupV1.isPresent()) {
|
||||
return groupV1.get().getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.whispersystems.signalservice.api.messages;
|
||||
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
|
||||
/**
|
||||
* Group information to include in SignalServiceMessages destined to v2 groups.
|
||||
* <p>
|
||||
* This class represents a "context" that is included with Signal Service messages
|
||||
* to make them group messages.
|
||||
*/
|
||||
public final class SignalServiceGroupV2 {
|
||||
|
||||
private final GroupMasterKey masterKey;
|
||||
private final int revision;
|
||||
private final byte[] signedGroupChange;
|
||||
|
||||
private SignalServiceGroupV2(Builder builder) {
|
||||
this.masterKey = builder.masterKey;
|
||||
this.revision = builder.revision;
|
||||
this.signedGroupChange = builder.signedGroupChange != null ? builder.signedGroupChange.clone() : null;
|
||||
}
|
||||
|
||||
public GroupMasterKey getMasterKey() {
|
||||
return masterKey;
|
||||
}
|
||||
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public byte[] getSignedGroupChange() {
|
||||
return signedGroupChange;
|
||||
}
|
||||
|
||||
public static Builder newBuilder(GroupMasterKey masterKey) {
|
||||
return new Builder(masterKey);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final GroupMasterKey masterKey;
|
||||
private int revision;
|
||||
private byte[] signedGroupChange;
|
||||
|
||||
private Builder(GroupMasterKey masterKey) {
|
||||
if (masterKey == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.masterKey = masterKey;
|
||||
}
|
||||
|
||||
Builder withRevision(int revision) {
|
||||
this.revision = revision;
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder withSignedGroupChange(byte[] signedGroupChange) {
|
||||
this.signedGroupChange = signedGroupChange;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalServiceGroupV2 build() {
|
||||
return new SignalServiceGroupV2(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.whispersystems.signalservice.internal.push;
|
||||
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupContext;
|
||||
|
||||
/**
|
||||
* Exception that indicates that the data message has a higher required protocol version than the
|
||||
@@ -10,16 +9,16 @@ import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
*/
|
||||
public class UnsupportedDataMessageException extends Exception {
|
||||
|
||||
private final int requiredVersion;
|
||||
private final String sender;
|
||||
private final int senderDevice;
|
||||
private final Optional<SignalServiceGroup> group;
|
||||
private final int requiredVersion;
|
||||
private final String sender;
|
||||
private final int senderDevice;
|
||||
private final Optional<SignalServiceGroupContext> group;
|
||||
|
||||
public UnsupportedDataMessageException(int currentVersion,
|
||||
int requiredVersion,
|
||||
String sender,
|
||||
int senderDevice,
|
||||
Optional<SignalServiceGroup> group)
|
||||
Optional<SignalServiceGroupContext> group)
|
||||
{
|
||||
super("Required version: " + requiredVersion + ", Our version: " + currentVersion);
|
||||
this.requiredVersion = requiredVersion;
|
||||
@@ -40,7 +39,7 @@ public class UnsupportedDataMessageException extends Exception {
|
||||
return senderDevice;
|
||||
}
|
||||
|
||||
public Optional<SignalServiceGroup> getGroup() {
|
||||
public Optional<SignalServiceGroupContext> getGroup() {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ message DataMessage {
|
||||
optional string body = 1;
|
||||
repeated AttachmentPointer attachments = 2;
|
||||
optional GroupContext group = 3;
|
||||
optional GroupContextV2 groupV2 = 15;
|
||||
optional uint32 flags = 4;
|
||||
optional uint32 expireTimer = 5;
|
||||
optional bytes profileKey = 6;
|
||||
@@ -412,6 +413,12 @@ message GroupContext {
|
||||
optional AttachmentPointer avatar = 5;
|
||||
}
|
||||
|
||||
message GroupContextV2 {
|
||||
optional bytes masterKey = 1;
|
||||
optional uint32 revision = 2;
|
||||
optional bytes groupChange = 3;
|
||||
}
|
||||
|
||||
message ContactDetails {
|
||||
message Avatar {
|
||||
optional string contentType = 1;
|
||||
|
||||
Reference in New Issue
Block a user