Update TextSecure envelope protobuf.

Support envelope 'content' field.

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2015-06-15 15:42:05 -07:00
parent 79f36664ef
commit 53bdd946d6
19 changed files with 438 additions and 284 deletions

View File

@ -1,3 +1,3 @@
all: all:
protoc --java_out=../src/main/java/ OutgoingMessageSignal.proto PubSubMessage.proto protoc --java_out=../src/main/java/ TextSecure.proto PubSubMessage.proto

View File

@ -19,23 +19,22 @@ package textsecure;
option java_package = "org.whispersystems.textsecuregcm.entities"; option java_package = "org.whispersystems.textsecuregcm.entities";
option java_outer_classname = "MessageProtos"; option java_outer_classname = "MessageProtos";
message OutgoingMessageSignal { message Envelope {
enum Type { enum Type {
UNKNOWN = 0; UNKNOWN = 0;
CIPHERTEXT = 1; CIPHERTEXT = 1;
KEY_EXCHANGE = 2; KEY_EXCHANGE = 2;
PREKEY_BUNDLE = 3; PREKEY_BUNDLE = 3;
// PLAINTEXT = 4;
RECEIPT = 5; RECEIPT = 5;
} }
optional uint32 type = 1; optional Type type = 1;
optional string source = 2; optional string source = 2;
optional uint32 sourceDevice = 7; optional uint32 sourceDevice = 7;
optional string relay = 3; optional string relay = 3;
// repeated string destinations = 4;
optional uint64 timestamp = 5; optional uint64 timestamp = 5;
optional bytes message = 6; optional bytes legacyMessage = 6; // Contains an encrypted DataMessage
optional bytes content = 8; // Contains an encrypted Content
} }
message ProvisioningUuid { message ProvisioningUuid {

View File

@ -23,7 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.entities.IncomingMessage; import org.whispersystems.textsecuregcm.entities.IncomingMessage;
import org.whispersystems.textsecuregcm.entities.IncomingMessageList; import org.whispersystems.textsecuregcm.entities.IncomingMessageList;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.entities.MessageResponse; import org.whispersystems.textsecuregcm.entities.MessageResponse;
import org.whispersystems.textsecuregcm.entities.MismatchedDevices; import org.whispersystems.textsecuregcm.entities.MismatchedDevices;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
@ -169,7 +169,7 @@ public class MessageController {
try { try {
Optional<OutgoingMessageEntity> message = messagesManager.delete(account.getNumber(), source, timestamp); Optional<OutgoingMessageEntity> message = messagesManager.delete(account.getNumber(), source, timestamp);
if (message.isPresent() && message.get().getType() != OutgoingMessageSignal.Type.RECEIPT_VALUE) { if (message.isPresent() && message.get().getType() != Envelope.Type.RECEIPT_VALUE) {
receiptSender.sendReceipt(account, receiptSender.sendReceipt(account,
message.get().getSource(), message.get().getSource(),
message.get().getTimestamp(), message.get().getTimestamp(),
@ -213,15 +213,20 @@ public class MessageController {
{ {
try { try {
Optional<byte[]> messageBody = getMessageBody(incomingMessage); Optional<byte[]> messageBody = getMessageBody(incomingMessage);
OutgoingMessageSignal.Builder messageBuilder = OutgoingMessageSignal.newBuilder(); Optional<byte[]> messageContent = getMessageContent(incomingMessage);
Envelope.Builder messageBuilder = Envelope.newBuilder();
messageBuilder.setType(incomingMessage.getType()) messageBuilder.setType(Envelope.Type.valueOf(incomingMessage.getType()))
.setSource(source.getNumber()) .setSource(source.getNumber())
.setTimestamp(timestamp == 0 ? System.currentTimeMillis() : timestamp) .setTimestamp(timestamp == 0 ? System.currentTimeMillis() : timestamp)
.setSourceDevice((int) source.getAuthenticatedDevice().get().getId()); .setSourceDevice((int) source.getAuthenticatedDevice().get().getId());
if (messageBody.isPresent()) { if (messageBody.isPresent()) {
messageBuilder.setMessage(ByteString.copyFrom(messageBody.get())); messageBuilder.setLegacyMessage(ByteString.copyFrom(messageBody.get()));
}
if (messageContent.isPresent()) {
messageBuilder.setContent(ByteString.copyFrom(messageContent.get()));
} }
if (source.getRelay().isPresent()) { if (source.getRelay().isPresent()) {
@ -343,6 +348,8 @@ public class MessageController {
} }
private Optional<byte[]> getMessageBody(IncomingMessage message) { private Optional<byte[]> getMessageBody(IncomingMessage message) {
if (Util.isEmpty(message.getBody())) return Optional.absent();
try { try {
return Optional.of(Base64.decode(message.getBody())); return Optional.of(Base64.decode(message.getBody()));
} catch (IOException ioe) { } catch (IOException ioe) {
@ -350,4 +357,15 @@ public class MessageController {
return Optional.absent(); return Optional.absent();
} }
} }
private Optional<byte[]> getMessageContent(IncomingMessage message) {
if (Util.isEmpty(message.getContent())) return Optional.absent();
try {
return Optional.of(Base64.decode(message.getContent()));
} catch (IOException ioe) {
logger.debug("Bad B64", ioe);
return Optional.absent();
}
}
} }

View File

@ -18,7 +18,7 @@ package org.whispersystems.textsecuregcm.entities;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.util.Base64; import org.whispersystems.textsecuregcm.util.Base64;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
@ -44,8 +44,7 @@ public class EncryptedOutgoingMessage {
private final byte[] serialized; private final byte[] serialized;
private final String serializedAndEncoded; private final String serializedAndEncoded;
public EncryptedOutgoingMessage(OutgoingMessageSignal outgoingMessage, public EncryptedOutgoingMessage(Envelope outgoingMessage, String signalingKey)
String signalingKey)
throws CryptoEncodingException throws CryptoEncodingException
{ {
byte[] plaintext = outgoingMessage.toByteArray(); byte[] plaintext = outgoingMessage.toByteArray();

View File

@ -34,9 +34,11 @@ public class IncomingMessage {
private int destinationRegistrationId; private int destinationRegistrationId;
@JsonProperty @JsonProperty
@NotEmpty
private String body; private String body;
@JsonProperty
private String content;
@JsonProperty @JsonProperty
private String relay; private String relay;
@ -67,4 +69,8 @@ public class IncomingMessage {
public int getDestinationRegistrationId() { public int getDestinationRegistrationId() {
return destinationRegistrationId; return destinationRegistrationId;
} }
public String getContent() {
return content;
}
} }

View File

@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: OutgoingMessageSignal.proto // source: TextSecure.proto
package org.whispersystems.textsecuregcm.entities; package org.whispersystems.textsecuregcm.entities;
@ -8,18 +8,18 @@ public final class MessageProtos {
public static void registerAllExtensions( public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) { com.google.protobuf.ExtensionRegistry registry) {
} }
public interface OutgoingMessageSignalOrBuilder public interface EnvelopeOrBuilder
extends com.google.protobuf.MessageOrBuilder { extends com.google.protobuf.MessageOrBuilder {
// optional uint32 type = 1; // optional .textsecure.Envelope.Type type = 1;
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
boolean hasType(); boolean hasType();
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
int getType(); org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType();
// optional string source = 2; // optional string source = 2;
/** /**
@ -64,50 +64,68 @@ public final class MessageProtos {
// optional uint64 timestamp = 5; // optional uint64 timestamp = 5;
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
boolean hasTimestamp(); boolean hasTimestamp();
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
long getTimestamp(); long getTimestamp();
// optional bytes message = 6; // optional bytes legacyMessage = 6;
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
boolean hasMessage(); boolean hasLegacyMessage();
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
com.google.protobuf.ByteString getMessage(); com.google.protobuf.ByteString getLegacyMessage();
// optional bytes content = 8;
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
boolean hasContent();
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
com.google.protobuf.ByteString getContent();
} }
/** /**
* Protobuf type {@code textsecure.OutgoingMessageSignal} * Protobuf type {@code textsecure.Envelope}
*/ */
public static final class OutgoingMessageSignal extends public static final class Envelope extends
com.google.protobuf.GeneratedMessage com.google.protobuf.GeneratedMessage
implements OutgoingMessageSignalOrBuilder { implements EnvelopeOrBuilder {
// Use OutgoingMessageSignal.newBuilder() to construct. // Use Envelope.newBuilder() to construct.
private OutgoingMessageSignal(com.google.protobuf.GeneratedMessage.Builder<?> builder) { private Envelope(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder); super(builder);
this.unknownFields = builder.getUnknownFields(); this.unknownFields = builder.getUnknownFields();
} }
private OutgoingMessageSignal(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } private Envelope(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final OutgoingMessageSignal defaultInstance; private static final Envelope defaultInstance;
public static OutgoingMessageSignal getDefaultInstance() { public static Envelope getDefaultInstance() {
return defaultInstance; return defaultInstance;
} }
public OutgoingMessageSignal getDefaultInstanceForType() { public Envelope getDefaultInstanceForType() {
return defaultInstance; return defaultInstance;
} }
@ -117,7 +135,7 @@ public final class MessageProtos {
getUnknownFields() { getUnknownFields() {
return this.unknownFields; return this.unknownFields;
} }
private OutgoingMessageSignal( private Envelope(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
@ -141,8 +159,14 @@ public final class MessageProtos {
break; break;
} }
case 8: { case 8: {
int rawValue = input.readEnum();
org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type value = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.valueOf(rawValue);
if (value == null) {
unknownFields.mergeVarintField(1, rawValue);
} else {
bitField0_ |= 0x00000001; bitField0_ |= 0x00000001;
type_ = input.readUInt32(); type_ = value;
}
break; break;
} }
case 18: { case 18: {
@ -162,7 +186,7 @@ public final class MessageProtos {
} }
case 50: { case 50: {
bitField0_ |= 0x00000020; bitField0_ |= 0x00000020;
message_ = input.readBytes(); legacyMessage_ = input.readBytes();
break; break;
} }
case 56: { case 56: {
@ -170,6 +194,11 @@ public final class MessageProtos {
sourceDevice_ = input.readUInt32(); sourceDevice_ = input.readUInt32();
break; break;
} }
case 66: {
bitField0_ |= 0x00000040;
content_ = input.readBytes();
break;
}
} }
} }
} catch (com.google.protobuf.InvalidProtocolBufferException e) { } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@ -184,33 +213,33 @@ public final class MessageProtos {
} }
public static final com.google.protobuf.Descriptors.Descriptor public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() { getDescriptor() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor;
} }
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() { internalGetFieldAccessorTable() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_fieldAccessorTable
.ensureFieldAccessorsInitialized( .ensureFieldAccessorsInitialized(
org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.class, org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.Builder.class); org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.class, org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Builder.class);
} }
public static com.google.protobuf.Parser<OutgoingMessageSignal> PARSER = public static com.google.protobuf.Parser<Envelope> PARSER =
new com.google.protobuf.AbstractParser<OutgoingMessageSignal>() { new com.google.protobuf.AbstractParser<Envelope>() {
public OutgoingMessageSignal parsePartialFrom( public Envelope parsePartialFrom(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return new OutgoingMessageSignal(input, extensionRegistry); return new Envelope(input, extensionRegistry);
} }
}; };
@java.lang.Override @java.lang.Override
public com.google.protobuf.Parser<OutgoingMessageSignal> getParserForType() { public com.google.protobuf.Parser<Envelope> getParserForType() {
return PARSER; return PARSER;
} }
/** /**
* Protobuf enum {@code textsecure.OutgoingMessageSignal.Type} * Protobuf enum {@code textsecure.Envelope.Type}
*/ */
public enum Type public enum Type
implements com.google.protobuf.ProtocolMessageEnum { implements com.google.protobuf.ProtocolMessageEnum {
@ -230,14 +259,10 @@ public final class MessageProtos {
* <code>PREKEY_BUNDLE = 3;</code> * <code>PREKEY_BUNDLE = 3;</code>
*/ */
PREKEY_BUNDLE(3, 3), PREKEY_BUNDLE(3, 3),
/**
* <code>PLAINTEXT = 4;</code>
*/
PLAINTEXT(4, 4),
/** /**
* <code>RECEIPT = 5;</code> * <code>RECEIPT = 5;</code>
*/ */
RECEIPT(5, 5), RECEIPT(4, 5),
; ;
/** /**
@ -256,10 +281,6 @@ public final class MessageProtos {
* <code>PREKEY_BUNDLE = 3;</code> * <code>PREKEY_BUNDLE = 3;</code>
*/ */
public static final int PREKEY_BUNDLE_VALUE = 3; public static final int PREKEY_BUNDLE_VALUE = 3;
/**
* <code>PLAINTEXT = 4;</code>
*/
public static final int PLAINTEXT_VALUE = 4;
/** /**
* <code>RECEIPT = 5;</code> * <code>RECEIPT = 5;</code>
*/ */
@ -274,7 +295,6 @@ public final class MessageProtos {
case 1: return CIPHERTEXT; case 1: return CIPHERTEXT;
case 2: return KEY_EXCHANGE; case 2: return KEY_EXCHANGE;
case 3: return PREKEY_BUNDLE; case 3: return PREKEY_BUNDLE;
case 4: return PLAINTEXT;
case 5: return RECEIPT; case 5: return RECEIPT;
default: return null; default: return null;
} }
@ -302,7 +322,7 @@ public final class MessageProtos {
} }
public static final com.google.protobuf.Descriptors.EnumDescriptor public static final com.google.protobuf.Descriptors.EnumDescriptor
getDescriptor() { getDescriptor() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDescriptor().getEnumTypes().get(0); return org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDescriptor().getEnumTypes().get(0);
} }
private static final Type[] VALUES = values(); private static final Type[] VALUES = values();
@ -324,23 +344,23 @@ public final class MessageProtos {
this.value = value; this.value = value;
} }
// @@protoc_insertion_point(enum_scope:textsecure.OutgoingMessageSignal.Type) // @@protoc_insertion_point(enum_scope:textsecure.Envelope.Type)
} }
private int bitField0_; private int bitField0_;
// optional uint32 type = 1; // optional .textsecure.Envelope.Type type = 1;
public static final int TYPE_FIELD_NUMBER = 1; public static final int TYPE_FIELD_NUMBER = 1;
private int type_; private org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type type_;
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public boolean hasType() { public boolean hasType() {
return ((bitField0_ & 0x00000001) == 0x00000001); return ((bitField0_ & 0x00000001) == 0x00000001);
} }
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public int getType() { public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType() {
return type_; return type_;
} }
@ -451,48 +471,73 @@ public final class MessageProtos {
private long timestamp_; private long timestamp_;
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public boolean hasTimestamp() { public boolean hasTimestamp() {
return ((bitField0_ & 0x00000010) == 0x00000010); return ((bitField0_ & 0x00000010) == 0x00000010);
} }
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public long getTimestamp() { public long getTimestamp() {
return timestamp_; return timestamp_;
} }
// optional bytes message = 6; // optional bytes legacyMessage = 6;
public static final int MESSAGE_FIELD_NUMBER = 6; public static final int LEGACYMESSAGE_FIELD_NUMBER = 6;
private com.google.protobuf.ByteString message_; private com.google.protobuf.ByteString legacyMessage_;
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public boolean hasMessage() { public boolean hasLegacyMessage() {
return ((bitField0_ & 0x00000020) == 0x00000020); return ((bitField0_ & 0x00000020) == 0x00000020);
} }
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public com.google.protobuf.ByteString getMessage() { public com.google.protobuf.ByteString getLegacyMessage() {
return message_; return legacyMessage_;
}
// optional bytes content = 8;
public static final int CONTENT_FIELD_NUMBER = 8;
private com.google.protobuf.ByteString content_;
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public boolean hasContent() {
return ((bitField0_ & 0x00000040) == 0x00000040);
}
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public com.google.protobuf.ByteString getContent() {
return content_;
} }
private void initFields() { private void initFields() {
type_ = 0; type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN;
source_ = ""; source_ = "";
sourceDevice_ = 0; sourceDevice_ = 0;
relay_ = ""; relay_ = "";
timestamp_ = 0L; timestamp_ = 0L;
message_ = com.google.protobuf.ByteString.EMPTY; legacyMessage_ = com.google.protobuf.ByteString.EMPTY;
content_ = com.google.protobuf.ByteString.EMPTY;
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
public final boolean isInitialized() { public final boolean isInitialized() {
@ -507,7 +552,7 @@ public final class MessageProtos {
throws java.io.IOException { throws java.io.IOException {
getSerializedSize(); getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) { if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeUInt32(1, type_); output.writeEnum(1, type_.getNumber());
} }
if (((bitField0_ & 0x00000002) == 0x00000002)) { if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(2, getSourceBytes()); output.writeBytes(2, getSourceBytes());
@ -519,11 +564,14 @@ public final class MessageProtos {
output.writeUInt64(5, timestamp_); output.writeUInt64(5, timestamp_);
} }
if (((bitField0_ & 0x00000020) == 0x00000020)) { if (((bitField0_ & 0x00000020) == 0x00000020)) {
output.writeBytes(6, message_); output.writeBytes(6, legacyMessage_);
} }
if (((bitField0_ & 0x00000004) == 0x00000004)) { if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeUInt32(7, sourceDevice_); output.writeUInt32(7, sourceDevice_);
} }
if (((bitField0_ & 0x00000040) == 0x00000040)) {
output.writeBytes(8, content_);
}
getUnknownFields().writeTo(output); getUnknownFields().writeTo(output);
} }
@ -535,7 +583,7 @@ public final class MessageProtos {
size = 0; size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) { if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(1, type_); .computeEnumSize(1, type_.getNumber());
} }
if (((bitField0_ & 0x00000002) == 0x00000002)) { if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
@ -551,12 +599,16 @@ public final class MessageProtos {
} }
if (((bitField0_ & 0x00000020) == 0x00000020)) { if (((bitField0_ & 0x00000020) == 0x00000020)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeBytesSize(6, message_); .computeBytesSize(6, legacyMessage_);
} }
if (((bitField0_ & 0x00000004) == 0x00000004)) { if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(7, sourceDevice_); .computeUInt32Size(7, sourceDevice_);
} }
if (((bitField0_ & 0x00000040) == 0x00000040)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(8, content_);
}
size += getUnknownFields().getSerializedSize(); size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size; memoizedSerializedSize = size;
return size; return size;
@ -569,53 +621,53 @@ public final class MessageProtos {
return super.writeReplace(); return super.writeReplace();
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
com.google.protobuf.ByteString data) com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data); return PARSER.parseFrom(data);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
com.google.protobuf.ByteString data, com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry); return PARSER.parseFrom(data, extensionRegistry);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom(byte[] data) public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data); return PARSER.parseFrom(data);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
byte[] data, byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry); return PARSER.parseFrom(data, extensionRegistry);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom(java.io.InputStream input) public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(java.io.InputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input); return PARSER.parseFrom(input);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
java.io.InputStream input, java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry); return PARSER.parseFrom(input, extensionRegistry);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseDelimitedFrom(java.io.InputStream input) public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseDelimitedFrom(input); return PARSER.parseDelimitedFrom(input);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseDelimitedFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseDelimitedFrom(
java.io.InputStream input, java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry); return PARSER.parseDelimitedFrom(input, extensionRegistry);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
com.google.protobuf.CodedInputStream input) com.google.protobuf.CodedInputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input); return PARSER.parseFrom(input);
} }
public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
@ -624,7 +676,7 @@ public final class MessageProtos {
public static Builder newBuilder() { return Builder.create(); } public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); } public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal prototype) { public static Builder newBuilder(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope prototype) {
return newBuilder().mergeFrom(prototype); return newBuilder().mergeFrom(prototype);
} }
public Builder toBuilder() { return newBuilder(this); } public Builder toBuilder() { return newBuilder(this); }
@ -636,24 +688,24 @@ public final class MessageProtos {
return builder; return builder;
} }
/** /**
* Protobuf type {@code textsecure.OutgoingMessageSignal} * Protobuf type {@code textsecure.Envelope}
*/ */
public static final class Builder extends public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder> com.google.protobuf.GeneratedMessage.Builder<Builder>
implements org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignalOrBuilder { implements org.whispersystems.textsecuregcm.entities.MessageProtos.EnvelopeOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() { getDescriptor() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor;
} }
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() { internalGetFieldAccessorTable() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_fieldAccessorTable
.ensureFieldAccessorsInitialized( .ensureFieldAccessorsInitialized(
org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.class, org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.Builder.class); org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.class, org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Builder.class);
} }
// Construct using org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.newBuilder() // Construct using org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.newBuilder()
private Builder() { private Builder() {
maybeForceBuilderInitialization(); maybeForceBuilderInitialization();
} }
@ -673,7 +725,7 @@ public final class MessageProtos {
public Builder clear() { public Builder clear() {
super.clear(); super.clear();
type_ = 0; type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN;
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
source_ = ""; source_ = "";
bitField0_ = (bitField0_ & ~0x00000002); bitField0_ = (bitField0_ & ~0x00000002);
@ -683,8 +735,10 @@ public final class MessageProtos {
bitField0_ = (bitField0_ & ~0x00000008); bitField0_ = (bitField0_ & ~0x00000008);
timestamp_ = 0L; timestamp_ = 0L;
bitField0_ = (bitField0_ & ~0x00000010); bitField0_ = (bitField0_ & ~0x00000010);
message_ = com.google.protobuf.ByteString.EMPTY; legacyMessage_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000020); bitField0_ = (bitField0_ & ~0x00000020);
content_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000040);
return this; return this;
} }
@ -694,23 +748,23 @@ public final class MessageProtos {
public com.google.protobuf.Descriptors.Descriptor public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() { getDescriptorForType() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor;
} }
public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal getDefaultInstanceForType() { public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope getDefaultInstanceForType() {
return org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDefaultInstance(); return org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDefaultInstance();
} }
public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal build() { public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope build() {
org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal result = buildPartial(); org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope result = buildPartial();
if (!result.isInitialized()) { if (!result.isInitialized()) {
throw newUninitializedMessageException(result); throw newUninitializedMessageException(result);
} }
return result; return result;
} }
public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal buildPartial() { public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope buildPartial() {
org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal result = new org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal(this); org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope result = new org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope(this);
int from_bitField0_ = bitField0_; int from_bitField0_ = bitField0_;
int to_bitField0_ = 0; int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) { if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
@ -736,23 +790,27 @@ public final class MessageProtos {
if (((from_bitField0_ & 0x00000020) == 0x00000020)) { if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
to_bitField0_ |= 0x00000020; to_bitField0_ |= 0x00000020;
} }
result.message_ = message_; result.legacyMessage_ = legacyMessage_;
if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
to_bitField0_ |= 0x00000040;
}
result.content_ = content_;
result.bitField0_ = to_bitField0_; result.bitField0_ = to_bitField0_;
onBuilt(); onBuilt();
return result; return result;
} }
public Builder mergeFrom(com.google.protobuf.Message other) { public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal) { if (other instanceof org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope) {
return mergeFrom((org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal)other); return mergeFrom((org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope)other);
} else { } else {
super.mergeFrom(other); super.mergeFrom(other);
return this; return this;
} }
} }
public Builder mergeFrom(org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal other) { public Builder mergeFrom(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope other) {
if (other == org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDefaultInstance()) return this; if (other == org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDefaultInstance()) return this;
if (other.hasType()) { if (other.hasType()) {
setType(other.getType()); setType(other.getType());
} }
@ -772,8 +830,11 @@ public final class MessageProtos {
if (other.hasTimestamp()) { if (other.hasTimestamp()) {
setTimestamp(other.getTimestamp()); setTimestamp(other.getTimestamp());
} }
if (other.hasMessage()) { if (other.hasLegacyMessage()) {
setMessage(other.getMessage()); setLegacyMessage(other.getLegacyMessage());
}
if (other.hasContent()) {
setContent(other.getContent());
} }
this.mergeUnknownFields(other.getUnknownFields()); this.mergeUnknownFields(other.getUnknownFields());
return this; return this;
@ -787,11 +848,11 @@ public final class MessageProtos {
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parsedMessage = null; org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parsedMessage = null;
try { try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) { } catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal) e.getUnfinishedMessage(); parsedMessage = (org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope) e.getUnfinishedMessage();
throw e; throw e;
} finally { } finally {
if (parsedMessage != null) { if (parsedMessage != null) {
@ -802,35 +863,38 @@ public final class MessageProtos {
} }
private int bitField0_; private int bitField0_;
// optional uint32 type = 1; // optional .textsecure.Envelope.Type type = 1;
private int type_ ; private org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN;
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public boolean hasType() { public boolean hasType() {
return ((bitField0_ & 0x00000001) == 0x00000001); return ((bitField0_ & 0x00000001) == 0x00000001);
} }
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public int getType() { public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType() {
return type_; return type_;
} }
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public Builder setType(int value) { public Builder setType(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001; bitField0_ |= 0x00000001;
type_ = value; type_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>optional uint32 type = 1;</code> * <code>optional .textsecure.Envelope.Type type = 1;</code>
*/ */
public Builder clearType() { public Builder clearType() {
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
type_ = 0; type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN;
onChanged(); onChanged();
return this; return this;
} }
@ -1020,30 +1084,18 @@ public final class MessageProtos {
private long timestamp_ ; private long timestamp_ ;
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public boolean hasTimestamp() { public boolean hasTimestamp() {
return ((bitField0_ & 0x00000010) == 0x00000010); return ((bitField0_ & 0x00000010) == 0x00000010);
} }
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public long getTimestamp() { public long getTimestamp() {
return timestamp_; return timestamp_;
} }
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public Builder setTimestamp(long value) { public Builder setTimestamp(long value) {
bitField0_ |= 0x00000010; bitField0_ |= 0x00000010;
@ -1053,10 +1105,6 @@ public final class MessageProtos {
} }
/** /**
* <code>optional uint64 timestamp = 5;</code> * <code>optional uint64 timestamp = 5;</code>
*
* <pre>
* repeated string destinations = 4;
* </pre>
*/ */
public Builder clearTimestamp() { public Builder clearTimestamp() {
bitField0_ = (bitField0_ & ~0x00000010); bitField0_ = (bitField0_ & ~0x00000010);
@ -1065,51 +1113,119 @@ public final class MessageProtos {
return this; return this;
} }
// optional bytes message = 6; // optional bytes legacyMessage = 6;
private com.google.protobuf.ByteString message_ = com.google.protobuf.ByteString.EMPTY; private com.google.protobuf.ByteString legacyMessage_ = com.google.protobuf.ByteString.EMPTY;
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public boolean hasMessage() { public boolean hasLegacyMessage() {
return ((bitField0_ & 0x00000020) == 0x00000020); return ((bitField0_ & 0x00000020) == 0x00000020);
} }
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public com.google.protobuf.ByteString getMessage() { public com.google.protobuf.ByteString getLegacyMessage() {
return message_; return legacyMessage_;
} }
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public Builder setMessage(com.google.protobuf.ByteString value) { public Builder setLegacyMessage(com.google.protobuf.ByteString value) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
bitField0_ |= 0x00000020; bitField0_ |= 0x00000020;
message_ = value; legacyMessage_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>optional bytes message = 6;</code> * <code>optional bytes legacyMessage = 6;</code>
*
* <pre>
* Contains an encrypted DataMessage
* </pre>
*/ */
public Builder clearMessage() { public Builder clearLegacyMessage() {
bitField0_ = (bitField0_ & ~0x00000020); bitField0_ = (bitField0_ & ~0x00000020);
message_ = getDefaultInstance().getMessage(); legacyMessage_ = getDefaultInstance().getLegacyMessage();
onChanged(); onChanged();
return this; return this;
} }
// @@protoc_insertion_point(builder_scope:textsecure.OutgoingMessageSignal) // optional bytes content = 8;
private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY;
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public boolean hasContent() {
return ((bitField0_ & 0x00000040) == 0x00000040);
}
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public com.google.protobuf.ByteString getContent() {
return content_;
}
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public Builder setContent(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000040;
content_ = value;
onChanged();
return this;
}
/**
* <code>optional bytes content = 8;</code>
*
* <pre>
* Contains an encrypted Content
* </pre>
*/
public Builder clearContent() {
bitField0_ = (bitField0_ & ~0x00000040);
content_ = getDefaultInstance().getContent();
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:textsecure.Envelope)
} }
static { static {
defaultInstance = new OutgoingMessageSignal(true); defaultInstance = new Envelope(true);
defaultInstance.initFields(); defaultInstance.initFields();
} }
// @@protoc_insertion_point(class_scope:textsecure.OutgoingMessageSignal) // @@protoc_insertion_point(class_scope:textsecure.Envelope)
} }
public interface ProvisioningUuidOrBuilder public interface ProvisioningUuidOrBuilder
@ -1584,10 +1700,10 @@ public final class MessageProtos {
} }
private static com.google.protobuf.Descriptors.Descriptor private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_OutgoingMessageSignal_descriptor; internal_static_textsecure_Envelope_descriptor;
private static private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable; internal_static_textsecure_Envelope_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_ProvisioningUuid_descriptor; internal_static_textsecure_ProvisioningUuid_descriptor;
private static private static
@ -1602,28 +1718,28 @@ public final class MessageProtos {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\033OutgoingMessageSignal.proto\022\ntextsecur" + "\n\020TextSecure.proto\022\ntextsecure\"\372\001\n\010Envel" +
"e\"\344\001\n\025OutgoingMessageSignal\022\014\n\004type\030\001 \001(" + "ope\022\'\n\004type\030\001 \001(\0162\031.textsecure.Envelope." +
"\r\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceDevice\030\007 \001(\r\022" + "Type\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceDevice\030\007 \001" +
"\r\n\005relay\030\003 \001(\t\022\021\n\ttimestamp\030\005 \001(\004\022\017\n\007mes" + "(\r\022\r\n\005relay\030\003 \001(\t\022\021\n\ttimestamp\030\005 \001(\004\022\025\n\r" +
"sage\030\006 \001(\014\"d\n\004Type\022\013\n\007UNKNOWN\020\000\022\016\n\nCIPHE" + "legacyMessage\030\006 \001(\014\022\017\n\007content\030\010 \001(\014\"U\n\004" +
"RTEXT\020\001\022\020\n\014KEY_EXCHANGE\020\002\022\021\n\rPREKEY_BUND" + "Type\022\013\n\007UNKNOWN\020\000\022\016\n\nCIPHERTEXT\020\001\022\020\n\014KEY" +
"LE\020\003\022\r\n\tPLAINTEXT\020\004\022\013\n\007RECEIPT\020\005\" \n\020Prov" + "_EXCHANGE\020\002\022\021\n\rPREKEY_BUNDLE\020\003\022\013\n\007RECEIP" +
"isioningUuid\022\014\n\004uuid\030\001 \001(\tB:\n)org.whispe" + "T\020\005\" \n\020ProvisioningUuid\022\014\n\004uuid\030\001 \001(\tB:\n" +
"rsystems.textsecuregcm.entitiesB\rMessage" + ")org.whispersystems.textsecuregcm.entiti" +
"Protos" "esB\rMessageProtos"
}; };
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
public com.google.protobuf.ExtensionRegistry assignDescriptors( public com.google.protobuf.ExtensionRegistry assignDescriptors(
com.google.protobuf.Descriptors.FileDescriptor root) { com.google.protobuf.Descriptors.FileDescriptor root) {
descriptor = root; descriptor = root;
internal_static_textsecure_OutgoingMessageSignal_descriptor = internal_static_textsecure_Envelope_descriptor =
getDescriptor().getMessageTypes().get(0); getDescriptor().getMessageTypes().get(0);
internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable = new internal_static_textsecure_Envelope_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_OutgoingMessageSignal_descriptor, internal_static_textsecure_Envelope_descriptor,
new java.lang.String[] { "Type", "Source", "SourceDevice", "Relay", "Timestamp", "Message", }); new java.lang.String[] { "Type", "Source", "SourceDevice", "Relay", "Timestamp", "LegacyMessage", "Content", });
internal_static_textsecure_ProvisioningUuid_descriptor = internal_static_textsecure_ProvisioningUuid_descriptor =
getDescriptor().getMessageTypes().get(1); getDescriptor().getMessageTypes().get(1);
internal_static_textsecure_ProvisioningUuid_fieldAccessorTable = new internal_static_textsecure_ProvisioningUuid_fieldAccessorTable = new

View File

@ -26,10 +26,14 @@ public class OutgoingMessageEntity {
@JsonProperty @JsonProperty
private byte[] message; private byte[] message;
@JsonProperty
private byte[] content;
public OutgoingMessageEntity() {} public OutgoingMessageEntity() {}
public OutgoingMessageEntity(long id, int type, String relay, long timestamp, public OutgoingMessageEntity(long id, int type, String relay, long timestamp,
String source, int sourceDevice, byte[] message) String source, int sourceDevice, byte[] message,
byte[] content)
{ {
this.id = id; this.id = id;
this.type = type; this.type = type;
@ -38,6 +42,7 @@ public class OutgoingMessageEntity {
this.source = source; this.source = source;
this.sourceDevice = sourceDevice; this.sourceDevice = sourceDevice;
this.message = message; this.message = message;
this.content = content;
} }
public int getType() { public int getType() {
@ -64,7 +69,12 @@ public class OutgoingMessageEntity {
return message; return message;
} }
public byte[] getContent() {
return content;
}
public long getId() { public long getId() {
return id; return id;
} }
} }

View File

@ -29,11 +29,9 @@ import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
import org.whispersystems.textsecuregcm.websocket.WebsocketAddress; import org.whispersystems.textsecuregcm.websocket.WebsocketAddress;
import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import io.dropwizard.lifecycle.Managed; import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal;
public class PushSender { public class PushSender {
@ -51,7 +49,7 @@ public class PushSender {
this.webSocketSender = websocketSender; this.webSocketSender = websocketSender;
} }
public void sendMessage(Account account, Device device, OutgoingMessageSignal message) public void sendMessage(Account account, Device device, Envelope message)
throws NotPushRegisteredException, TransientPushFailureException throws NotPushRegisteredException, TransientPushFailureException
{ {
if (device.getGcmId() != null) sendGcmMessage(account, device, message); if (device.getGcmId() != null) sendGcmMessage(account, device, message);
@ -64,21 +62,21 @@ public class PushSender {
return webSocketSender; return webSocketSender;
} }
private void sendGcmMessage(Account account, Device device, OutgoingMessageSignal message) private void sendGcmMessage(Account account, Device device, Envelope message)
throws TransientPushFailureException, NotPushRegisteredException throws TransientPushFailureException, NotPushRegisteredException
{ {
if (device.getFetchesMessages()) sendNotificationGcmMessage(account, device, message); if (device.getFetchesMessages()) sendNotificationGcmMessage(account, device, message);
else sendPayloadGcmMessage(account, device, message); else sendPayloadGcmMessage(account, device, message);
} }
private void sendPayloadGcmMessage(Account account, Device device, OutgoingMessageSignal message) private void sendPayloadGcmMessage(Account account, Device device, Envelope message)
throws TransientPushFailureException, NotPushRegisteredException throws TransientPushFailureException, NotPushRegisteredException
{ {
try { try {
String number = account.getNumber(); String number = account.getNumber();
long deviceId = device.getId(); long deviceId = device.getId();
String registrationId = device.getGcmId(); String registrationId = device.getGcmId();
boolean isReceipt = message.getType() == OutgoingMessageSignal.Type.RECEIPT_VALUE; boolean isReceipt = message.getType() == Envelope.Type.RECEIPT;
EncryptedOutgoingMessage encryptedMessage = new EncryptedOutgoingMessage(message, device.getSignalingKey()); EncryptedOutgoingMessage encryptedMessage = new EncryptedOutgoingMessage(message, device.getSignalingKey());
GcmMessage gcmMessage = new GcmMessage(registrationId, number, (int) deviceId, GcmMessage gcmMessage = new GcmMessage(registrationId, number, (int) deviceId,
encryptedMessage.toEncodedString(), isReceipt, false); encryptedMessage.toEncodedString(), isReceipt, false);
@ -89,7 +87,7 @@ public class PushSender {
} }
} }
private void sendNotificationGcmMessage(Account account, Device device, OutgoingMessageSignal message) private void sendNotificationGcmMessage(Account account, Device device, Envelope message)
throws TransientPushFailureException throws TransientPushFailureException
{ {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, message, WebsocketSender.Type.GCM); DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, message, WebsocketSender.Type.GCM);
@ -102,12 +100,12 @@ public class PushSender {
} }
} }
private void sendApnMessage(Account account, Device device, OutgoingMessageSignal outgoingMessage) private void sendApnMessage(Account account, Device device, Envelope outgoingMessage)
throws TransientPushFailureException throws TransientPushFailureException
{ {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.APN); DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.APN);
if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != OutgoingMessageSignal.Type.RECEIPT_VALUE) { if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != Envelope.Type.RECEIPT) {
ApnMessage apnMessage; ApnMessage apnMessage;
if (!Util.isEmpty(device.getVoipApnId())) { if (!Util.isEmpty(device.getVoipApnId())) {
@ -127,7 +125,7 @@ public class PushSender {
} }
} }
private void sendWebSocketMessage(Account account, Device device, OutgoingMessageSignal outgoingMessage) private void sendWebSocketMessage(Account account, Device device, Envelope outgoingMessage)
{ {
webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.WEB); webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.WEB);
} }

View File

@ -2,7 +2,7 @@ package org.whispersystems.textsecuregcm.push;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import org.whispersystems.textsecuregcm.controllers.NoSuchUserException; import org.whispersystems.textsecuregcm.controllers.NoSuchUserException;
import org.whispersystems.textsecuregcm.entities.MessageProtos; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.federation.NoSuchPeerException; import org.whispersystems.textsecuregcm.federation.NoSuchPeerException;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Account;
@ -57,13 +57,11 @@ public class ReceiptSender {
{ {
Account destinationAccount = getDestinationAccount(destination); Account destinationAccount = getDestinationAccount(destination);
Set<Device> destinationDevices = destinationAccount.getDevices(); Set<Device> destinationDevices = destinationAccount.getDevices();
Envelope.Builder message = Envelope.newBuilder()
MessageProtos.OutgoingMessageSignal.Builder message =
MessageProtos.OutgoingMessageSignal.newBuilder()
.setSource(source.getNumber()) .setSource(source.getNumber())
.setSourceDevice((int) source.getAuthenticatedDevice().get().getId()) .setSourceDevice((int) source.getAuthenticatedDevice().get().getId())
.setTimestamp(messageId) .setTimestamp(messageId)
.setType(MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE); .setType(Envelope.Type.RECEIPT);
if (source.getRelay().isPresent()) { if (source.getRelay().isPresent()) {
message.setRelay(source.getRelay().get()); message.setRelay(source.getRelay().get());

View File

@ -31,7 +31,7 @@ import org.whispersystems.textsecuregcm.websocket.ProvisioningAddress;
import org.whispersystems.textsecuregcm.websocket.WebsocketAddress; import org.whispersystems.textsecuregcm.websocket.WebsocketAddress;
import static com.codahale.metrics.MetricRegistry.name; import static com.codahale.metrics.MetricRegistry.name;
import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage;
public class WebsocketSender { public class WebsocketSender {
@ -66,7 +66,7 @@ public class WebsocketSender {
this.pubSubManager = pubSubManager; this.pubSubManager = pubSubManager;
} }
public DeliveryStatus sendMessage(Account account, Device device, OutgoingMessageSignal message, Type channel) { public DeliveryStatus sendMessage(Account account, Device device, Envelope message, Type channel) {
WebsocketAddress address = new WebsocketAddress(account.getNumber(), device.getId()); WebsocketAddress address = new WebsocketAddress(account.getNumber(), device.getId());
PubSubMessage pubSubMessage = PubSubMessage.newBuilder() PubSubMessage pubSubMessage = PubSubMessage.newBuilder()
.setType(PubSubMessage.Type.DELIVER) .setType(PubSubMessage.Type.DELIVER)

View File

@ -10,7 +10,7 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate; import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper; import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
import org.skife.jdbi.v2.tweak.ResultSetMapper; import org.skife.jdbi.v2.tweak.ResultSetMapper;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
@ -33,11 +33,12 @@ public abstract class Messages {
private static final String DESTINATION = "destination"; private static final String DESTINATION = "destination";
private static final String DESTINATION_DEVICE = "destination_device"; private static final String DESTINATION_DEVICE = "destination_device";
private static final String MESSAGE = "message"; private static final String MESSAGE = "message";
private static final String CONTENT = "content";
@SqlQuery("INSERT INTO messages (" + TYPE + ", " + RELAY + ", " + TIMESTAMP + ", " + SOURCE + ", " + SOURCE_DEVICE + ", " + DESTINATION + ", " + DESTINATION_DEVICE + ", " + MESSAGE + ") " + @SqlQuery("INSERT INTO messages (" + TYPE + ", " + RELAY + ", " + TIMESTAMP + ", " + SOURCE + ", " + SOURCE_DEVICE + ", " + DESTINATION + ", " + DESTINATION_DEVICE + ", " + MESSAGE + ", " + CONTENT + ") " +
"VALUES (:type, :relay, :timestamp, :source, :source_device, :destination, :destination_device, :message) " + "VALUES (:type, :relay, :timestamp, :source, :source_device, :destination, :destination_device, :message, :content) " +
"RETURNING (SELECT COUNT(id) FROM messages WHERE " + DESTINATION + " = :destination AND " + DESTINATION_DEVICE + " = :destination_device AND " + TYPE + " != " + OutgoingMessageSignal.Type.RECEIPT_VALUE + ")") "RETURNING (SELECT COUNT(id) FROM messages WHERE " + DESTINATION + " = :destination AND " + DESTINATION_DEVICE + " = :destination_device AND " + TYPE + " != " + Envelope.Type.RECEIPT_VALUE + ")")
abstract int store(@MessageBinder OutgoingMessageSignal message, abstract int store(@MessageBinder Envelope message,
@Bind("destination") String destination, @Bind("destination") String destination,
@Bind("destination_device") long destinationDevice); @Bind("destination_device") long destinationDevice);
@ -71,7 +72,8 @@ public abstract class Messages {
resultSet.getLong(TIMESTAMP), resultSet.getLong(TIMESTAMP),
resultSet.getString(SOURCE), resultSet.getString(SOURCE),
resultSet.getInt(SOURCE_DEVICE), resultSet.getInt(SOURCE_DEVICE),
resultSet.getBytes(MESSAGE)); resultSet.getBytes(MESSAGE),
resultSet.getBytes(CONTENT));
} }
} }
@ -82,18 +84,19 @@ public abstract class Messages {
public static class AccountBinderFactory implements BinderFactory { public static class AccountBinderFactory implements BinderFactory {
@Override @Override
public Binder build(Annotation annotation) { public Binder build(Annotation annotation) {
return new Binder<MessageBinder, OutgoingMessageSignal>() { return new Binder<MessageBinder, Envelope>() {
@Override @Override
public void bind(SQLStatement<?> sql, public void bind(SQLStatement<?> sql,
MessageBinder accountBinder, MessageBinder accountBinder,
OutgoingMessageSignal message) Envelope message)
{ {
sql.bind(TYPE, message.getType()); sql.bind(TYPE, message.getType().getNumber());
sql.bind(RELAY, message.getRelay()); sql.bind(RELAY, message.getRelay());
sql.bind(TIMESTAMP, message.getTimestamp()); sql.bind(TIMESTAMP, message.getTimestamp());
sql.bind(SOURCE, message.getSource()); sql.bind(SOURCE, message.getSource());
sql.bind(SOURCE_DEVICE, message.getSourceDevice()); sql.bind(SOURCE_DEVICE, message.getSourceDevice());
sql.bind(MESSAGE, message.getMessage().toByteArray()); sql.bind(MESSAGE, message.hasLegacyMessage() ? message.getLegacyMessage().toByteArray() : null);
sql.bind(CONTENT, message.hasContent() ? message.getContent().toByteArray() : null);
} }
}; };
} }

View File

@ -2,9 +2,8 @@ package org.whispersystems.textsecuregcm.storage;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
import org.whispersystems.textsecuregcm.util.Pair;
import java.util.List; import java.util.List;
@ -16,7 +15,7 @@ public class MessagesManager {
this.messages = messages; this.messages = messages;
} }
public int insert(String destination, long destinationDevice, OutgoingMessageSignal message) { public int insert(String destination, long destinationDevice, Envelope message) {
return this.messages.store(message, destination, destinationDevice) + 1; return this.messages.store(message, destination, destinationDevice) + 1;
} }

View File

@ -4,9 +4,8 @@ import com.google.protobuf.InvalidProtocolBufferException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.dispatch.DispatchChannel; import org.whispersystems.dispatch.DispatchChannel;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PubSubProtos;
import org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; import org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage;
public class DeadLetterHandler implements DispatchChannel { public class DeadLetterHandler implements DispatchChannel {
@ -29,7 +28,7 @@ public class DeadLetterHandler implements DispatchChannel {
switch (pubSubMessage.getType().getNumber()) { switch (pubSubMessage.getType().getNumber()) {
case PubSubMessage.Type.DELIVER_VALUE: case PubSubMessage.Type.DELIVER_VALUE:
OutgoingMessageSignal message = OutgoingMessageSignal.parseFrom(pubSubMessage.getContent()); Envelope message = Envelope.parseFrom(pubSubMessage.getContent());
messagesManager.insert(address.getNumber(), address.getDeviceId(), message); messagesManager.insert(address.getNumber(), address.getDeviceId(), message);
break; break;
} }

View File

@ -29,7 +29,7 @@ import javax.ws.rs.WebApplicationException;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage;
public class WebSocketConnection implements DispatchChannel { public class WebSocketConnection implements DispatchChannel {
@ -69,7 +69,7 @@ public class WebSocketConnection implements DispatchChannel {
processStoredMessages(); processStoredMessages();
break; break;
case PubSubMessage.Type.DELIVER_VALUE: case PubSubMessage.Type.DELIVER_VALUE:
sendMessage(OutgoingMessageSignal.parseFrom(pubSubMessage.getContent()), Optional.<Long>absent()); sendMessage(Envelope.parseFrom(pubSubMessage.getContent()), Optional.<Long>absent());
break; break;
default: default:
logger.warn("Unknown pubsub message: " + pubSubMessage.getType().getNumber()); logger.warn("Unknown pubsub message: " + pubSubMessage.getType().getNumber());
@ -88,7 +88,7 @@ public class WebSocketConnection implements DispatchChannel {
processStoredMessages(); processStoredMessages();
} }
private void sendMessage(final OutgoingMessageSignal message, private void sendMessage(final Envelope message,
final Optional<Long> storedMessageId) final Optional<Long> storedMessageId)
{ {
try { try {
@ -99,7 +99,7 @@ public class WebSocketConnection implements DispatchChannel {
Futures.addCallback(response, new FutureCallback<WebSocketResponseMessage>() { Futures.addCallback(response, new FutureCallback<WebSocketResponseMessage>() {
@Override @Override
public void onSuccess(@Nullable WebSocketResponseMessage response) { public void onSuccess(@Nullable WebSocketResponseMessage response) {
boolean isReceipt = message.getType() == OutgoingMessageSignal.Type.RECEIPT_VALUE; boolean isReceipt = message.getType() == Envelope.Type.RECEIPT;
if (isSuccessResponse(response)) { if (isSuccessResponse(response)) {
if (storedMessageId.isPresent()) messagesManager.delete(account.getNumber(), storedMessageId.get()); if (storedMessageId.isPresent()) messagesManager.delete(account.getNumber(), storedMessageId.get());
@ -123,7 +123,7 @@ public class WebSocketConnection implements DispatchChannel {
} }
} }
private void requeueMessage(OutgoingMessageSignal message) { private void requeueMessage(Envelope message) {
try { try {
pushSender.sendMessage(account, device, message); pushSender.sendMessage(account, device, message);
} catch (NotPushRegisteredException | TransientPushFailureException e) { } catch (NotPushRegisteredException | TransientPushFailureException e) {
@ -132,7 +132,7 @@ public class WebSocketConnection implements DispatchChannel {
} }
} }
private void sendDeliveryReceiptFor(OutgoingMessageSignal message) { private void sendDeliveryReceiptFor(Envelope message) {
try { try {
receiptSender.sendReceipt(account, message.getSource(), message.getTimestamp(), receiptSender.sendReceipt(account, message.getSource(), message.getTimestamp(),
message.hasRelay() ? Optional.of(message.getRelay()) : message.hasRelay() ? Optional.of(message.getRelay()) :
@ -148,13 +148,20 @@ public class WebSocketConnection implements DispatchChannel {
List<OutgoingMessageEntity> messages = messagesManager.getMessagesForDevice(account.getNumber(), device.getId()); List<OutgoingMessageEntity> messages = messagesManager.getMessagesForDevice(account.getNumber(), device.getId());
for (OutgoingMessageEntity message : messages) { for (OutgoingMessageEntity message : messages) {
OutgoingMessageSignal.Builder builder = OutgoingMessageSignal.newBuilder() Envelope.Builder builder = Envelope.newBuilder()
.setType(message.getType()) .setType(Envelope.Type.valueOf(message.getType()))
.setMessage(ByteString.copyFrom(message.getMessage()))
.setSourceDevice(message.getSourceDevice()) .setSourceDevice(message.getSourceDevice())
.setSource(message.getSource()) .setSource(message.getSource())
.setTimestamp(message.getTimestamp()); .setTimestamp(message.getTimestamp());
if (message.getMessage() != null) {
builder.setLegacyMessage(ByteString.copyFrom(message.getMessage()));
}
if (message.getContent() != null) {
builder.setContent(ByteString.copyFrom(message.getContent()));
}
if (message.getRelay() != null && !message.getRelay().isEmpty()) { if (message.getRelay() != null && !message.getRelay().isEmpty()) {
builder.setRelay(message.getRelay()); builder.setRelay(message.getRelay());
} }

View File

@ -57,4 +57,12 @@
</createIndex> </createIndex>
</changeSet> </changeSet>
<changeSet id="2" author="moxie">
<addColumn tableName="messages">
<column name="content" type="bytea"/>
</addColumn>
<dropNotNullConstraint tableName="messages" columnName="message"/>
</changeSet>
</databaseChangeLog> </databaseChangeLog>

View File

@ -106,7 +106,7 @@ public class FederatedControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(204))); assertThat("Good Response", response.getStatus(), is(equalTo(204)));
verify(pushSender).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.Envelope.class));
} }
@Test @Test

View File

@ -3,13 +3,12 @@ package org.whispersystems.textsecuregcm.tests.controllers;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse;
import org.hamcrest.CoreMatchers;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.whispersystems.textsecuregcm.controllers.MessageController; import org.whispersystems.textsecuregcm.controllers.MessageController;
import org.whispersystems.textsecuregcm.entities.IncomingMessageList; import org.whispersystems.textsecuregcm.entities.IncomingMessageList;
import org.whispersystems.textsecuregcm.entities.MessageProtos; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.entities.MismatchedDevices; import org.whispersystems.textsecuregcm.entities.MismatchedDevices;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntityList; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntityList;
@ -25,7 +24,6 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.SystemMapper;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.util.HashSet; import java.util.HashSet;
@ -100,7 +98,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200))); assertThat("Good Response", response.getStatus(), is(equalTo(200)));
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
} }
@Test @Test
@ -114,7 +112,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200))); assertThat("Good Response", response.getStatus(), is(equalTo(200)));
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
} }
@Test @Test
@ -164,7 +162,7 @@ public class MessageControllerTest {
assertThat("Good Response Code", response.getStatus(), is(equalTo(200))); assertThat("Good Response Code", response.getStatus(), is(equalTo(200)));
verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
} }
@Test @Test
@ -193,8 +191,8 @@ public class MessageControllerTest {
final long timestampTwo = 313388; final long timestampTwo = 313388;
List<OutgoingMessageEntity> messages = new LinkedList<OutgoingMessageEntity>() {{ List<OutgoingMessageEntity> messages = new LinkedList<OutgoingMessageEntity>() {{
add(new OutgoingMessageEntity(1L, MessageProtos.OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes())); add(new OutgoingMessageEntity(1L, Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null));
add(new OutgoingMessageEntity(2L, MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null)); add(new OutgoingMessageEntity(2L, Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null));
}}; }};
when(messagesManager.getMessagesForDevice(eq(AuthHelper.VALID_NUMBER), eq(1L))).thenReturn(messages); when(messagesManager.getMessagesForDevice(eq(AuthHelper.VALID_NUMBER), eq(1L))).thenReturn(messages);
@ -220,15 +218,15 @@ public class MessageControllerTest {
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31337)) when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31337))
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, .thenReturn(Optional.of(new OutgoingMessageEntity(31337L,
MessageProtos.OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, Envelope.Type.CIPHERTEXT_VALUE,
null, timestamp, null, timestamp,
"+14152222222", 1, "hi".getBytes()))); "+14152222222", 1, "hi".getBytes(), null)));
when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31338)) when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31338))
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, .thenReturn(Optional.of(new OutgoingMessageEntity(31337L,
MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE, Envelope.Type.RECEIPT_VALUE,
null, System.currentTimeMillis(), null, System.currentTimeMillis(),
"+14152222222", 1, null))); "+14152222222", 1, null, null)));
when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31339)) when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31339))

View File

@ -8,6 +8,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.whispersystems.textsecuregcm.controllers.ReceiptController; import org.whispersystems.textsecuregcm.controllers.ReceiptController;
import org.whispersystems.textsecuregcm.entities.MessageProtos; import org.whispersystems.textsecuregcm.entities.MessageProtos;
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.push.PushSender; import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.push.ReceiptSender; import org.whispersystems.textsecuregcm.push.ReceiptSender;
@ -70,7 +71,7 @@ public class ReceiptControllerTest {
assertThat(response.getStatus() == 204); assertThat(response.getStatus() == 204);
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
} }
@Test @Test
@ -82,7 +83,7 @@ public class ReceiptControllerTest {
assertThat(response.getStatus() == 204); assertThat(response.getStatus() == 204);
verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
} }

View File

@ -5,7 +5,6 @@ import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
@ -20,7 +19,6 @@ import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PubSubManager; import org.whispersystems.textsecuregcm.storage.PubSubManager;
import org.whispersystems.textsecuregcm.storage.PubSubProtos; import org.whispersystems.textsecuregcm.storage.PubSubProtos;
import org.whispersystems.textsecuregcm.util.Base64; import org.whispersystems.textsecuregcm.util.Base64;
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.websocket.AuthenticatedConnectListener; import org.whispersystems.textsecuregcm.websocket.AuthenticatedConnectListener;
import org.whispersystems.textsecuregcm.websocket.WebSocketAccountAuthenticator; import org.whispersystems.textsecuregcm.websocket.WebSocketAccountAuthenticator;
import org.whispersystems.textsecuregcm.websocket.WebSocketConnection; import org.whispersystems.textsecuregcm.websocket.WebSocketConnection;
@ -28,7 +26,6 @@ import org.whispersystems.textsecuregcm.websocket.WebsocketAddress;
import org.whispersystems.websocket.WebSocketClient; import org.whispersystems.websocket.WebSocketClient;
import org.whispersystems.websocket.messages.WebSocketResponseMessage; import org.whispersystems.websocket.messages.WebSocketResponseMessage;
import org.whispersystems.websocket.session.WebSocketSessionContext; import org.whispersystems.websocket.session.WebSocketSessionContext;
import org.whispersystems.websocket.setup.WebSocketConnectListener;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -38,12 +35,10 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import io.dropwizard.auth.basic.BasicCredentials; import io.dropwizard.auth.basic.BasicCredentials;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
public class WebSocketConnectionTest { public class WebSocketConnectionTest {
@ -169,20 +164,20 @@ public class WebSocketConnectionTest {
@Test @Test
public void testOnlineSend() throws Exception { public void testOnlineSend() throws Exception {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
OutgoingMessageSignal firstMessage = OutgoingMessageSignal.newBuilder() Envelope firstMessage = Envelope.newBuilder()
.setMessage(ByteString.copyFrom("first".getBytes())) .setLegacyMessage(ByteString.copyFrom("first".getBytes()))
.setSource("sender1") .setSource("sender1")
.setTimestamp(System.currentTimeMillis()) .setTimestamp(System.currentTimeMillis())
.setSourceDevice(1) .setSourceDevice(1)
.setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) .setType(Envelope.Type.CIPHERTEXT)
.build(); .build();
OutgoingMessageSignal secondMessage = OutgoingMessageSignal.newBuilder() Envelope secondMessage = Envelope.newBuilder()
.setMessage(ByteString.copyFrom("second".getBytes())) .setLegacyMessage(ByteString.copyFrom("second".getBytes()))
.setSource("sender2") .setSource("sender2")
.setTimestamp(System.currentTimeMillis()) .setTimestamp(System.currentTimeMillis())
.setSourceDevice(2) .setSourceDevice(2)
.setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) .setType(Envelope.Type.CIPHERTEXT)
.build(); .build();
List<OutgoingMessageEntity> pendingMessages = new LinkedList<>(); List<OutgoingMessageEntity> pendingMessages = new LinkedList<>();
@ -246,15 +241,15 @@ public class WebSocketConnectionTest {
futures.get(0).setException(new IOException()); futures.get(0).setException(new IOException());
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.<String>absent())); verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.<String>absent()));
verify(pushSender, times(1)).sendMessage(eq(account), eq(device), any(OutgoingMessageSignal.class)); verify(pushSender, times(1)).sendMessage(eq(account), eq(device), any(Envelope.class));
connection.onDispatchUnsubscribed(websocketAddress.serialize()); connection.onDispatchUnsubscribed(websocketAddress.serialize());
verify(client).close(anyInt(), anyString()); verify(client).close(anyInt(), anyString());
} }
private OutgoingMessageEntity createMessage(long id, String sender, long timestamp, boolean receipt, String content) { private OutgoingMessageEntity createMessage(long id, String sender, long timestamp, boolean receipt, String content) {
return new OutgoingMessageEntity(id, receipt ? OutgoingMessageSignal.Type.RECEIPT_VALUE : OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, return new OutgoingMessageEntity(id, receipt ? Envelope.Type.RECEIPT_VALUE : Envelope.Type.CIPHERTEXT_VALUE,
null, timestamp, sender, 1, content.getBytes()); null, timestamp, sender, 1, content.getBytes(), null);
} }
} }