Support for device management and contact requests.

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2015-06-19 21:44:38 -07:00
parent 0437bde205
commit 4731a34252
14 changed files with 901 additions and 26 deletions

View File

@ -1,5 +1,5 @@
subprojects { subprojects {
ext.version_number = "1.6.0-RC4" ext.version_number = "1.6.0-RC19"
ext.group_info = "org.whispersystems" ext.group_info = "org.whispersystems"
ext.axolotl_version = "1.3.1" ext.axolotl_version = "1.3.1"

View File

@ -26,6 +26,7 @@ import org.whispersystems.libaxolotl.ecc.ECPublicKey;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.libaxolotl.util.guava.Optional;
import org.whispersystems.textsecure.api.messages.multidevice.DeviceInfo;
import org.whispersystems.textsecure.api.push.ContactTokenDetails; import org.whispersystems.textsecure.api.push.ContactTokenDetails;
import org.whispersystems.textsecure.api.push.SignedPreKeyEntity; import org.whispersystems.textsecure.api.push.SignedPreKeyEntity;
import org.whispersystems.textsecure.api.push.TrustStore; import org.whispersystems.textsecure.api.push.TrustStore;
@ -234,6 +235,14 @@ public class TextSecureAccountManager {
this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext); this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext);
} }
public List<DeviceInfo> getDevices() throws IOException {
return this.pushServiceSocket.getDevices();
}
public void removeDevice(long deviceId) throws IOException {
this.pushServiceSocket.removeDevice(deviceId);
}
private String createDirectoryServerToken(String e164number, boolean urlSafe) { private String createDirectoryServerToken(String e164number, boolean urlSafe) {
try { try {
MessageDigest digest = MessageDigest.getInstance("SHA1"); MessageDigest digest = MessageDigest.getInstance("SHA1");

View File

@ -191,11 +191,12 @@ public class TextSecureMessageSender {
} }
private byte[] createMultiDeviceContactsContent(TextSecureAttachmentStream contacts) throws IOException { private byte[] createMultiDeviceContactsContent(TextSecureAttachmentStream contacts) throws IOException {
SyncMessage.Builder builder = SyncMessage.newBuilder(); Content.Builder container = Content.newBuilder();
SyncMessage.Builder builder = SyncMessage.newBuilder();
builder.setContacts(SyncMessage.Contacts.newBuilder() builder.setContacts(SyncMessage.Contacts.newBuilder()
.setBlob(createAttachmentPointer(contacts))); .setBlob(createAttachmentPointer(contacts)));
return builder.build().toByteArray(); return container.setSyncMessage(builder).build().toByteArray();
} }
private byte[] createSentTranscriptMessage(byte[] content, Optional<TextSecureAddress> recipient, long timestamp) { private byte[] createSentTranscriptMessage(byte[] content, Optional<TextSecureAddress> recipient, long timestamp) {

View File

@ -39,6 +39,7 @@ import org.whispersystems.textsecure.api.messages.TextSecureContent;
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope; import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;
import org.whispersystems.textsecure.api.messages.TextSecureGroup; import org.whispersystems.textsecure.api.messages.TextSecureGroup;
import org.whispersystems.textsecure.api.messages.TextSecureDataMessage; import org.whispersystems.textsecure.api.messages.TextSecureDataMessage;
import org.whispersystems.textsecure.api.messages.multidevice.RequestMessage;
import org.whispersystems.textsecure.api.messages.multidevice.SentTranscriptMessage; import org.whispersystems.textsecure.api.messages.multidevice.SentTranscriptMessage;
import org.whispersystems.textsecure.api.messages.multidevice.TextSecureSyncMessage; import org.whispersystems.textsecure.api.messages.multidevice.TextSecureSyncMessage;
import org.whispersystems.textsecure.api.push.TextSecureAddress; import org.whispersystems.textsecure.api.push.TextSecureAddress;
@ -175,8 +176,12 @@ public class TextSecureCipher {
if (content.hasSent()) { if (content.hasSent()) {
SyncMessage.Sent sentContent = content.getSent(); SyncMessage.Sent sentContent = content.getSent();
return new TextSecureSyncMessage(new SentTranscriptMessage(sentContent.getDestination(), return new TextSecureSyncMessage(new SentTranscriptMessage(sentContent.getDestination(),
sentContent.getTimestamp(), sentContent.getTimestamp(),
createTextSecureMessage(envelope, sentContent.getMessage()))); createTextSecureMessage(envelope, sentContent.getMessage())));
}
if (content.hasRequest()) {
return new TextSecureSyncMessage(new RequestMessage(content.getRequest()));
} }
return new TextSecureSyncMessage(); return new TextSecureSyncMessage();

View File

@ -4,6 +4,7 @@ import org.whispersystems.textsecure.internal.push.TextSecureProtos;
import org.whispersystems.textsecure.internal.util.Util; import org.whispersystems.textsecure.internal.util.Util;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
public class DeviceContactsOutputStream { public class DeviceContactsOutputStream {
@ -25,7 +26,16 @@ public class DeviceContactsOutputStream {
private void writeAvatarImage(DeviceContact contact) throws IOException { private void writeAvatarImage(DeviceContact contact) throws IOException {
if (contact.getAvatar().isPresent()) { if (contact.getAvatar().isPresent()) {
Util.copy(contact.getAvatar().get().getInputStream(), out); InputStream in = contact.getAvatar().get().getInputStream();
byte[] buffer = new byte[4096];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
} }
} }
@ -41,6 +51,7 @@ public class DeviceContactsOutputStream {
TextSecureProtos.ContactDetails.Avatar.Builder avatarBuilder = TextSecureProtos.ContactDetails.Avatar.newBuilder(); TextSecureProtos.ContactDetails.Avatar.Builder avatarBuilder = TextSecureProtos.ContactDetails.Avatar.newBuilder();
avatarBuilder.setContentType(contact.getAvatar().get().getContentType()); avatarBuilder.setContentType(contact.getAvatar().get().getContentType());
avatarBuilder.setLength(contact.getAvatar().get().getLength()); avatarBuilder.setLength(contact.getAvatar().get().getLength());
contactDetails.setAvatar(avatarBuilder);
} }
byte[] serializedContactDetails = contactDetails.build().toByteArray(); byte[] serializedContactDetails = contactDetails.build().toByteArray();

View File

@ -0,0 +1,36 @@
package org.whispersystems.textsecure.api.messages.multidevice;
import com.fasterxml.jackson.annotation.JsonProperty;
public class DeviceInfo {
@JsonProperty
private long id;
@JsonProperty
private String name;
@JsonProperty
private long created;
@JsonProperty
private long lastSeen;
public DeviceInfo() {}
public long getId() {
return id;
}
public String getName() {
return name;
}
public long getCreated() {
return created;
}
public long getLastSeen() {
return lastSeen;
}
}

View File

@ -0,0 +1,16 @@
package org.whispersystems.textsecure.api.messages.multidevice;
import org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request;
public class RequestMessage {
private final Request request;
public RequestMessage(Request request) {
this.request = request;
}
public boolean isContactsRequest() {
return request.getType() == Request.Type.CONTACTS;
}
}

View File

@ -9,29 +9,41 @@ public class TextSecureSyncMessage {
private final Optional<SentTranscriptMessage> sent; private final Optional<SentTranscriptMessage> sent;
private final Optional<TextSecureAttachment> contacts; private final Optional<TextSecureAttachment> contacts;
private final Optional<TextSecureGroup> group; private final Optional<TextSecureGroup> group;
private final Optional<RequestMessage> request;
public TextSecureSyncMessage() { public TextSecureSyncMessage() {
this.sent = Optional.absent(); this.sent = Optional.absent();
this.contacts = Optional.absent(); this.contacts = Optional.absent();
this.group = Optional.absent(); this.group = Optional.absent();
this.request = Optional.absent();
} }
public TextSecureSyncMessage(SentTranscriptMessage sent) { public TextSecureSyncMessage(SentTranscriptMessage sent) {
this.sent = Optional.of(sent); this.sent = Optional.of(sent);
this.contacts = Optional.absent(); this.contacts = Optional.absent();
this.group = Optional.absent(); this.group = Optional.absent();
this.request = Optional.absent();
} }
public TextSecureSyncMessage(TextSecureAttachment contacts) { public TextSecureSyncMessage(TextSecureAttachment contacts) {
this.contacts = Optional.of(contacts); this.contacts = Optional.of(contacts);
this.sent = Optional.absent(); this.sent = Optional.absent();
this.group = Optional.absent(); this.group = Optional.absent();
this.request = Optional.absent();
} }
public TextSecureSyncMessage(TextSecureGroup group) { public TextSecureSyncMessage(TextSecureGroup group) {
this.group = Optional.of(group); this.group = Optional.of(group);
this.sent = Optional.absent(); this.sent = Optional.absent();
this.contacts = Optional.absent(); this.contacts = Optional.absent();
this.request = Optional.absent();
}
public TextSecureSyncMessage(RequestMessage contactsRequest) {
this.request = Optional.of(contactsRequest);
this.sent = Optional.absent();
this.contacts = Optional.absent();
this.group = Optional.absent();
} }
public Optional<SentTranscriptMessage> getSent() { public Optional<SentTranscriptMessage> getSent() {
@ -46,4 +58,8 @@ public class TextSecureSyncMessage {
return contacts; return contacts;
} }
public Optional<RequestMessage> getRequest() {
return request;
}
} }

View File

@ -0,0 +1,19 @@
package org.whispersystems.textsecure.internal.push;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.textsecure.api.messages.multidevice.DeviceInfo;
import java.util.List;
public class DeviceInfoList {
@JsonProperty
private List<DeviceInfo> devices;
public DeviceInfoList() {}
public List<DeviceInfo> getDevices() {
return devices;
}
}

View File

@ -0,0 +1,20 @@
package org.whispersystems.textsecure.internal.push;
import com.fasterxml.jackson.annotation.JsonProperty;
public class DeviceLimit {
@JsonProperty
private int current;
@JsonProperty
private int max;
public int getCurrent() {
return current;
}
public int getMax() {
return max;
}
}

View File

@ -0,0 +1,20 @@
package org.whispersystems.textsecure.internal.push;
import org.whispersystems.textsecure.api.push.exceptions.NonSuccessfulResponseCodeException;
public class DeviceLimitExceededException extends NonSuccessfulResponseCodeException {
private final DeviceLimit deviceLimit;
public DeviceLimitExceededException(DeviceLimit deviceLimit) {
this.deviceLimit = deviceLimit;
}
public int getCurrent() {
return deviceLimit.getCurrent();
}
public int getMax() {
return deviceLimit.getMax();
}
}

View File

@ -27,6 +27,7 @@ import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.libaxolotl.util.guava.Optional;
import org.whispersystems.textsecure.api.crypto.AttachmentCipherOutputStream; import org.whispersystems.textsecure.api.crypto.AttachmentCipherOutputStream;
import org.whispersystems.textsecure.api.messages.multidevice.DeviceInfo;
import org.whispersystems.textsecure.api.push.ContactTokenDetails; import org.whispersystems.textsecure.api.push.ContactTokenDetails;
import org.whispersystems.textsecure.api.push.TextSecureAddress; import org.whispersystems.textsecure.api.push.TextSecureAddress;
import org.whispersystems.textsecure.api.push.SignedPreKeyEntity; import org.whispersystems.textsecure.api.push.SignedPreKeyEntity;
@ -86,6 +87,7 @@ public class PushServiceSocket {
private static final String PROVISIONING_CODE_PATH = "/v1/devices/provisioning/code"; private static final String PROVISIONING_CODE_PATH = "/v1/devices/provisioning/code";
private static final String PROVISIONING_MESSAGE_PATH = "/v1/provisioning/%s"; private static final String PROVISIONING_MESSAGE_PATH = "/v1/provisioning/%s";
private static final String DEVICE_PATH = "/v1/devices/%s";
private static final String DIRECTORY_TOKENS_PATH = "/v1/directory/tokens"; private static final String DIRECTORY_TOKENS_PATH = "/v1/directory/tokens";
private static final String DIRECTORY_VERIFY_PATH = "/v1/directory/%s"; private static final String DIRECTORY_VERIFY_PATH = "/v1/directory/%s";
@ -126,6 +128,15 @@ public class PushServiceSocket {
return JsonUtil.fromJson(responseText, DeviceCode.class).getVerificationCode(); return JsonUtil.fromJson(responseText, DeviceCode.class).getVerificationCode();
} }
public List<DeviceInfo> getDevices() throws IOException {
String responseText = makeRequest(String.format(DEVICE_PATH, ""), "GET", null);
return JsonUtil.fromJson(responseText, DeviceInfoList.class).getDevices();
}
public void removeDevice(long deviceId) throws IOException {
makeRequest(String.format(DEVICE_PATH, String.valueOf(deviceId)), "DELETE", null);
}
public void sendProvisioningMessage(String destination, byte[] body) throws IOException { public void sendProvisioningMessage(String destination, byte[] body) throws IOException {
makeRequest(String.format(PROVISIONING_MESSAGE_PATH, destination), "PUT", makeRequest(String.format(PROVISIONING_MESSAGE_PATH, destination), "PUT",
JsonUtil.toJson(new ProvisioningMessage(Base64.encodeBytes(body)))); JsonUtil.toJson(new ProvisioningMessage(Base64.encodeBytes(body))));
@ -483,6 +494,13 @@ public class PushServiceSocket {
throw new PushNetworkException(e); throw new PushNetworkException(e);
} }
throw new StaleDevicesException(JsonUtil.fromJson(response, StaleDevices.class)); throw new StaleDevicesException(JsonUtil.fromJson(response, StaleDevices.class));
case 411:
try {
response = Util.readFully(connection.getErrorStream());
} catch (IOException e) {
throw new PushNetworkException(e);
}
throw new DeviceLimitExceededException(JsonUtil.fromJson(response, DeviceLimit.class));
case 417: case 417:
throw new ExpectationFailedException(); throw new ExpectationFailedException();
} }

View File

@ -3150,6 +3150,20 @@ public final class TextSecureProtos {
* <code>optional .textsecure.SyncMessage.Group group = 3;</code> * <code>optional .textsecure.SyncMessage.Group group = 3;</code>
*/ */
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.GroupOrBuilder getGroupOrBuilder(); org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.GroupOrBuilder getGroupOrBuilder();
// optional .textsecure.SyncMessage.Request request = 4;
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
boolean hasRequest();
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest();
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder();
} }
/** /**
* Protobuf type {@code textsecure.SyncMessage} * Protobuf type {@code textsecure.SyncMessage}
@ -3241,6 +3255,19 @@ public final class TextSecureProtos {
bitField0_ |= 0x00000004; bitField0_ |= 0x00000004;
break; break;
} }
case 34: {
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder subBuilder = null;
if (((bitField0_ & 0x00000008) == 0x00000008)) {
subBuilder = request_.toBuilder();
}
request_ = input.readMessage(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(request_);
request_ = subBuilder.buildPartial();
}
bitField0_ |= 0x00000008;
break;
}
} }
} }
} catch (com.google.protobuf.InvalidProtocolBufferException e) { } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@ -5038,6 +5065,493 @@ public final class TextSecureProtos {
// @@protoc_insertion_point(class_scope:textsecure.SyncMessage.Group) // @@protoc_insertion_point(class_scope:textsecure.SyncMessage.Group)
} }
public interface RequestOrBuilder
extends com.google.protobuf.MessageOrBuilder {
// optional .textsecure.SyncMessage.Request.Type type = 1;
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
boolean hasType();
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type getType();
}
/**
* Protobuf type {@code textsecure.SyncMessage.Request}
*/
public static final class Request extends
com.google.protobuf.GeneratedMessage
implements RequestOrBuilder {
// Use Request.newBuilder() to construct.
private Request(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder);
this.unknownFields = builder.getUnknownFields();
}
private Request(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final Request defaultInstance;
public static Request getDefaultInstance() {
return defaultInstance;
}
public Request getDefaultInstanceForType() {
return defaultInstance;
}
private final com.google.protobuf.UnknownFieldSet unknownFields;
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private Request(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
initFields();
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(input, unknownFields,
extensionRegistry, tag)) {
done = true;
}
break;
}
case 8: {
int rawValue = input.readEnum();
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type value = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type.valueOf(rawValue);
if (value == null) {
unknownFields.mergeVarintField(1, rawValue);
} else {
bitField0_ |= 0x00000001;
type_ = value;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.internal_static_textsecure_SyncMessage_Request_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.internal_static_textsecure_SyncMessage_Request_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.class, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder.class);
}
public static com.google.protobuf.Parser<Request> PARSER =
new com.google.protobuf.AbstractParser<Request>() {
public Request parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new Request(input, extensionRegistry);
}
};
@java.lang.Override
public com.google.protobuf.Parser<Request> getParserForType() {
return PARSER;
}
/**
* Protobuf enum {@code textsecure.SyncMessage.Request.Type}
*/
public enum Type
implements com.google.protobuf.ProtocolMessageEnum {
/**
* <code>UNKNOWN = 0;</code>
*/
UNKNOWN(0, 0),
/**
* <code>CONTACTS = 1;</code>
*/
CONTACTS(1, 1),
;
/**
* <code>UNKNOWN = 0;</code>
*/
public static final int UNKNOWN_VALUE = 0;
/**
* <code>CONTACTS = 1;</code>
*/
public static final int CONTACTS_VALUE = 1;
public final int getNumber() { return value; }
public static Type valueOf(int value) {
switch (value) {
case 0: return UNKNOWN;
case 1: return CONTACTS;
default: return null;
}
}
public static com.google.protobuf.Internal.EnumLiteMap<Type>
internalGetValueMap() {
return internalValueMap;
}
private static com.google.protobuf.Internal.EnumLiteMap<Type>
internalValueMap =
new com.google.protobuf.Internal.EnumLiteMap<Type>() {
public Type findValueByNumber(int number) {
return Type.valueOf(number);
}
};
public final com.google.protobuf.Descriptors.EnumValueDescriptor
getValueDescriptor() {
return getDescriptor().getValues().get(index);
}
public final com.google.protobuf.Descriptors.EnumDescriptor
getDescriptorForType() {
return getDescriptor();
}
public static final com.google.protobuf.Descriptors.EnumDescriptor
getDescriptor() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDescriptor().getEnumTypes().get(0);
}
private static final Type[] VALUES = values();
public static Type valueOf(
com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
if (desc.getType() != getDescriptor()) {
throw new java.lang.IllegalArgumentException(
"EnumValueDescriptor is not for this type.");
}
return VALUES[desc.getIndex()];
}
private final int index;
private final int value;
private Type(int index, int value) {
this.index = index;
this.value = value;
}
// @@protoc_insertion_point(enum_scope:textsecure.SyncMessage.Request.Type)
}
private int bitField0_;
// optional .textsecure.SyncMessage.Request.Type type = 1;
public static final int TYPE_FIELD_NUMBER = 1;
private org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type type_;
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public boolean hasType() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type getType() {
return type_;
}
private void initFields() {
type_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type.UNKNOWN;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
memoizedIsInitialized = 1;
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeEnum(1, type_.getNumber());
}
getUnknownFields().writeTo(output);
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeEnumSize(1, type_.getNumber());
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
}
private static final long serialVersionUID = 0L;
@java.lang.Override
protected java.lang.Object writeReplace()
throws java.io.ObjectStreamException {
return super.writeReplace();
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request prototype) {
return newBuilder().mergeFrom(prototype);
}
public Builder toBuilder() { return newBuilder(this); }
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code textsecure.SyncMessage.Request}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder>
implements org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.internal_static_textsecure_SyncMessage_Request_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.internal_static_textsecure_SyncMessage_Request_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.class, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder.class);
}
// Construct using org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
}
}
private static Builder create() {
return new Builder();
}
public Builder clear() {
super.clear();
type_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type.UNKNOWN;
bitField0_ = (bitField0_ & ~0x00000001);
return this;
}
public Builder clone() {
return create().mergeFrom(buildPartial());
}
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.internal_static_textsecure_SyncMessage_Request_descriptor;
}
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getDefaultInstanceForType() {
return org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance();
}
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request build() {
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request buildPartial() {
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request result = new org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request(this);
int from_bitField0_ = bitField0_;
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
to_bitField0_ |= 0x00000001;
}
result.type_ = type_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request) {
return mergeFrom((org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request other) {
if (other == org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance()) return this;
if (other.hasType()) {
setType(other.getType());
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
public final boolean isInitialized() {
return true;
}
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request) e.getUnfinishedMessage();
throw e;
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
// optional .textsecure.SyncMessage.Request.Type type = 1;
private org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type type_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type.UNKNOWN;
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public boolean hasType() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type getType() {
return type_;
}
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public Builder setType(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
type_ = value;
onChanged();
return this;
}
/**
* <code>optional .textsecure.SyncMessage.Request.Type type = 1;</code>
*/
public Builder clearType() {
bitField0_ = (bitField0_ & ~0x00000001);
type_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type.UNKNOWN;
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:textsecure.SyncMessage.Request)
}
static {
defaultInstance = new Request(true);
defaultInstance.initFields();
}
// @@protoc_insertion_point(class_scope:textsecure.SyncMessage.Request)
}
private int bitField0_; private int bitField0_;
// optional .textsecure.SyncMessage.Sent sent = 1; // optional .textsecure.SyncMessage.Sent sent = 1;
public static final int SENT_FIELD_NUMBER = 1; public static final int SENT_FIELD_NUMBER = 1;
@ -5105,10 +5619,33 @@ public final class TextSecureProtos {
return group_; return group_;
} }
// optional .textsecure.SyncMessage.Request request = 4;
public static final int REQUEST_FIELD_NUMBER = 4;
private org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request request_;
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public boolean hasRequest() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest() {
return request_;
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder() {
return request_;
}
private void initFields() { private void initFields() {
sent_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Sent.getDefaultInstance(); sent_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Sent.getDefaultInstance();
contacts_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Contacts.getDefaultInstance(); contacts_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Contacts.getDefaultInstance();
group_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Group.getDefaultInstance(); group_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Group.getDefaultInstance();
request_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance();
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
public final boolean isInitialized() { public final boolean isInitialized() {
@ -5131,6 +5668,9 @@ public final class TextSecureProtos {
if (((bitField0_ & 0x00000004) == 0x00000004)) { if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeMessage(3, group_); output.writeMessage(3, group_);
} }
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeMessage(4, request_);
}
getUnknownFields().writeTo(output); getUnknownFields().writeTo(output);
} }
@ -5152,6 +5692,10 @@ public final class TextSecureProtos {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeMessageSize(3, group_); .computeMessageSize(3, group_);
} }
if (((bitField0_ & 0x00000008) == 0x00000008)) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(4, request_);
}
size += getUnknownFields().getSerializedSize(); size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size; memoizedSerializedSize = size;
return size; return size;
@ -5263,6 +5807,7 @@ public final class TextSecureProtos {
getSentFieldBuilder(); getSentFieldBuilder();
getContactsFieldBuilder(); getContactsFieldBuilder();
getGroupFieldBuilder(); getGroupFieldBuilder();
getRequestFieldBuilder();
} }
} }
private static Builder create() { private static Builder create() {
@ -5289,6 +5834,12 @@ public final class TextSecureProtos {
groupBuilder_.clear(); groupBuilder_.clear();
} }
bitField0_ = (bitField0_ & ~0x00000004); bitField0_ = (bitField0_ & ~0x00000004);
if (requestBuilder_ == null) {
request_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance();
} else {
requestBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
return this; return this;
} }
@ -5341,6 +5892,14 @@ public final class TextSecureProtos {
} else { } else {
result.group_ = groupBuilder_.build(); result.group_ = groupBuilder_.build();
} }
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000008;
}
if (requestBuilder_ == null) {
result.request_ = request_;
} else {
result.request_ = requestBuilder_.build();
}
result.bitField0_ = to_bitField0_; result.bitField0_ = to_bitField0_;
onBuilt(); onBuilt();
return result; return result;
@ -5366,6 +5925,9 @@ public final class TextSecureProtos {
if (other.hasGroup()) { if (other.hasGroup()) {
mergeGroup(other.getGroup()); mergeGroup(other.getGroup());
} }
if (other.hasRequest()) {
mergeRequest(other.getRequest());
}
this.mergeUnknownFields(other.getUnknownFields()); this.mergeUnknownFields(other.getUnknownFields());
return this; return this;
} }
@ -5744,6 +6306,123 @@ public final class TextSecureProtos {
return groupBuilder_; return groupBuilder_;
} }
// optional .textsecure.SyncMessage.Request request = 4;
private org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request request_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance();
private com.google.protobuf.SingleFieldBuilder<
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder> requestBuilder_;
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public boolean hasRequest() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest() {
if (requestBuilder_ == null) {
return request_;
} else {
return requestBuilder_.getMessage();
}
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public Builder setRequest(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request value) {
if (requestBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
request_ = value;
onChanged();
} else {
requestBuilder_.setMessage(value);
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public Builder setRequest(
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder builderForValue) {
if (requestBuilder_ == null) {
request_ = builderForValue.build();
onChanged();
} else {
requestBuilder_.setMessage(builderForValue.build());
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public Builder mergeRequest(org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request value) {
if (requestBuilder_ == null) {
if (((bitField0_ & 0x00000008) == 0x00000008) &&
request_ != org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance()) {
request_ =
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.newBuilder(request_).mergeFrom(value).buildPartial();
} else {
request_ = value;
}
onChanged();
} else {
requestBuilder_.mergeFrom(value);
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public Builder clearRequest() {
if (requestBuilder_ == null) {
request_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance();
onChanged();
} else {
requestBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
return this;
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder getRequestBuilder() {
bitField0_ |= 0x00000008;
onChanged();
return getRequestFieldBuilder().getBuilder();
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder() {
if (requestBuilder_ != null) {
return requestBuilder_.getMessageOrBuilder();
} else {
return request_;
}
}
/**
* <code>optional .textsecure.SyncMessage.Request request = 4;</code>
*/
private com.google.protobuf.SingleFieldBuilder<
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder>
getRequestFieldBuilder() {
if (requestBuilder_ == null) {
requestBuilder_ = new com.google.protobuf.SingleFieldBuilder<
org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder, org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder>(
request_,
getParentForChildren(),
isClean());
request_ = null;
}
return requestBuilder_;
}
// @@protoc_insertion_point(builder_scope:textsecure.SyncMessage) // @@protoc_insertion_point(builder_scope:textsecure.SyncMessage)
} }
@ -8919,6 +9598,11 @@ public final class TextSecureProtos {
private static private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_SyncMessage_Group_fieldAccessorTable; internal_static_textsecure_SyncMessage_Group_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_SyncMessage_Request_descriptor;
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_SyncMessage_Request_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_AttachmentPointer_descriptor; internal_static_textsecure_AttachmentPointer_descriptor;
private static private static
@ -8961,28 +9645,32 @@ public final class TextSecureProtos {
"ge\022\014\n\004body\030\001 \001(\t\0222\n\013attachments\030\002 \003(\0132\035." + "ge\022\014\n\004body\030\001 \001(\t\0222\n\013attachments\030\002 \003(\0132\035." +
"textsecure.AttachmentPointer\022\'\n\005group\030\003 " + "textsecure.AttachmentPointer\022\'\n\005group\030\003 " +
"\001(\0132\030.textsecure.GroupContext\022\r\n\005flags\030\004" + "\001(\0132\030.textsecure.GroupContext\022\r\n\005flags\030\004" +
" \001(\r\"\030\n\005Flags\022\017\n\013END_SESSION\020\001\"\340\002\n\013SyncM" + " \001(\r\"\030\n\005Flags\022\017\n\013END_SESSION\020\001\"\364\003\n\013SyncM" +
"essage\022*\n\004sent\030\001 \001(\0132\034.textsecure.SyncMe" + "essage\022*\n\004sent\030\001 \001(\0132\034.textsecure.SyncMe" +
"ssage.Sent\0222\n\010contacts\030\002 \001(\0132 .textsecur" + "ssage.Sent\0222\n\010contacts\030\002 \001(\0132 .textsecur" +
"e.SyncMessage.Contacts\022,\n\005group\030\003 \001(\0132\035." + "e.SyncMessage.Contacts\022,\n\005group\030\003 \001(\0132\035." +
"textsecure.SyncMessage.Group\032X\n\004Sent\022\023\n\013" + "textsecure.SyncMessage.Group\0220\n\007request\030" +
"destination\030\001 \001(\t\022\021\n\ttimestamp\030\002 \001(\004\022(\n\007" + "\004 \001(\0132\037.textsecure.SyncMessage.Request\032X" +
"message\030\003 \001(\0132\027.textsecure.DataMessage\0327", "\n\004Sent\022\023\n\013destination\030\001 \001(\t\022\021\n\ttimestamp",
"\n\010Contacts\022+\n\004blob\030\001 \001(\0132\035.textsecure.At" + "\030\002 \001(\004\022(\n\007message\030\003 \001(\0132\027.textsecure.Dat" +
"tachmentPointer\0320\n\005Group\022\'\n\005group\030\001 \001(\0132" + "aMessage\0327\n\010Contacts\022+\n\004blob\030\001 \001(\0132\035.tex" +
"\030.textsecure.GroupContext\"A\n\021AttachmentP" + "tsecure.AttachmentPointer\0320\n\005Group\022\'\n\005gr" +
"ointer\022\n\n\002id\030\001 \001(\006\022\023\n\013contentType\030\002 \001(\t\022" + "oup\030\001 \001(\0132\030.textsecure.GroupContext\032`\n\007R" +
"\013\n\003key\030\003 \001(\014\"\315\001\n\014GroupContext\022\n\n\002id\030\001 \001(" + "equest\0222\n\004type\030\001 \001(\0162$.textsecure.SyncMe" +
"\014\022+\n\004type\030\002 \001(\0162\035.textsecure.GroupContex" + "ssage.Request.Type\"!\n\004Type\022\013\n\007UNKNOWN\020\000\022" +
"t.Type\022\014\n\004name\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\022-\n" + "\014\n\010CONTACTS\020\001\"A\n\021AttachmentPointer\022\n\n\002id" +
"\006avatar\030\005 \001(\0132\035.textsecure.AttachmentPoi" + "\030\001 \001(\006\022\023\n\013contentType\030\002 \001(\t\022\013\n\003key\030\003 \001(\014" +
"nter\"6\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n" + "\"\315\001\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022+\n\004type\030\002 " +
"\007DELIVER\020\002\022\010\n\004QUIT\020\003\"\220\001\n\016ContactDetails\022", "\001(\0162\035.textsecure.GroupContext.Type\022\014\n\004na",
"\016\n\006number\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\0221\n\006avatar\030" + "me\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\022-\n\006avatar\030\005 \001(" +
"\003 \001(\0132!.textsecure.ContactDetails.Avatar" + "\0132\035.textsecure.AttachmentPointer\"6\n\004Type" +
"\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006lengt" + "\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010" +
"h\030\002 \001(\004B?\n+org.whispersystems.textsecure" + "\n\004QUIT\020\003\"\220\001\n\016ContactDetails\022\016\n\006number\030\001 " +
".internal.pushB\020TextSecureProtos" "\001(\t\022\014\n\004name\030\002 \001(\t\0221\n\006avatar\030\003 \001(\0132!.text" +
"secure.ContactDetails.Avatar\032-\n\006Avatar\022\023" +
"\n\013contentType\030\001 \001(\t\022\016\n\006length\030\002 \001(\004B?\n+o" +
"rg.whispersystems.textsecure.internal.pu" +
"shB\020TextSecureProtos"
}; };
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() {
@ -9012,7 +9700,7 @@ public final class TextSecureProtos {
internal_static_textsecure_SyncMessage_fieldAccessorTable = new internal_static_textsecure_SyncMessage_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_SyncMessage_descriptor, internal_static_textsecure_SyncMessage_descriptor,
new java.lang.String[] { "Sent", "Contacts", "Group", }); new java.lang.String[] { "Sent", "Contacts", "Group", "Request", });
internal_static_textsecure_SyncMessage_Sent_descriptor = internal_static_textsecure_SyncMessage_Sent_descriptor =
internal_static_textsecure_SyncMessage_descriptor.getNestedTypes().get(0); internal_static_textsecure_SyncMessage_descriptor.getNestedTypes().get(0);
internal_static_textsecure_SyncMessage_Sent_fieldAccessorTable = new internal_static_textsecure_SyncMessage_Sent_fieldAccessorTable = new
@ -9031,6 +9719,12 @@ public final class TextSecureProtos {
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_SyncMessage_Group_descriptor, internal_static_textsecure_SyncMessage_Group_descriptor,
new java.lang.String[] { "Group", }); new java.lang.String[] { "Group", });
internal_static_textsecure_SyncMessage_Request_descriptor =
internal_static_textsecure_SyncMessage_descriptor.getNestedTypes().get(3);
internal_static_textsecure_SyncMessage_Request_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_SyncMessage_Request_descriptor,
new java.lang.String[] { "Type", });
internal_static_textsecure_AttachmentPointer_descriptor = internal_static_textsecure_AttachmentPointer_descriptor =
getDescriptor().getMessageTypes().get(4); getDescriptor().getMessageTypes().get(4);
internal_static_textsecure_AttachmentPointer_fieldAccessorTable = new internal_static_textsecure_AttachmentPointer_fieldAccessorTable = new

View File

@ -52,9 +52,19 @@ message SyncMessage {
optional GroupContext group = 1; optional GroupContext group = 1;
} }
message Request {
enum Type {
UNKNOWN = 0;
CONTACTS = 1;
}
optional Type type = 1;
}
optional Sent sent = 1; optional Sent sent = 1;
optional Contacts contacts = 2; optional Contacts contacts = 2;
optional Group group = 3; optional Group group = 3;
optional Request request = 4;
} }
message AttachmentPointer { message AttachmentPointer {