diff --git a/build.gradle b/build.gradle index 61f98e31d7..f0f6336a31 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ subprojects { - ext.version_number = "1.6.0-RC4" + ext.version_number = "1.6.0-RC19" ext.group_info = "org.whispersystems" ext.axolotl_version = "1.3.1" diff --git a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java index 67bbf3bdbe..83364f7139 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java @@ -26,6 +26,7 @@ import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; 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.SignedPreKeyEntity; import org.whispersystems.textsecure.api.push.TrustStore; @@ -234,6 +235,14 @@ public class TextSecureAccountManager { this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext); } + public List 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) { try { MessageDigest digest = MessageDigest.getInstance("SHA1"); diff --git a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java index 803605fb2f..88a4f17337 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java @@ -191,11 +191,12 @@ public class TextSecureMessageSender { } 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() .setBlob(createAttachmentPointer(contacts))); - return builder.build().toByteArray(); + return container.setSyncMessage(builder).build().toByteArray(); } private byte[] createSentTranscriptMessage(byte[] content, Optional recipient, long timestamp) { diff --git a/java/src/main/java/org/whispersystems/textsecure/api/crypto/TextSecureCipher.java b/java/src/main/java/org/whispersystems/textsecure/api/crypto/TextSecureCipher.java index b3f9b12080..c50e96dab4 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/crypto/TextSecureCipher.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/crypto/TextSecureCipher.java @@ -39,6 +39,7 @@ import org.whispersystems.textsecure.api.messages.TextSecureContent; import org.whispersystems.textsecure.api.messages.TextSecureEnvelope; import org.whispersystems.textsecure.api.messages.TextSecureGroup; 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.TextSecureSyncMessage; import org.whispersystems.textsecure.api.push.TextSecureAddress; @@ -175,8 +176,12 @@ public class TextSecureCipher { if (content.hasSent()) { SyncMessage.Sent sentContent = content.getSent(); return new TextSecureSyncMessage(new SentTranscriptMessage(sentContent.getDestination(), - sentContent.getTimestamp(), - createTextSecureMessage(envelope, sentContent.getMessage()))); + sentContent.getTimestamp(), + createTextSecureMessage(envelope, sentContent.getMessage()))); + } + + if (content.hasRequest()) { + return new TextSecureSyncMessage(new RequestMessage(content.getRequest())); } return new TextSecureSyncMessage(); diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java index 881a52958f..ea160e5191 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java @@ -4,6 +4,7 @@ import org.whispersystems.textsecure.internal.push.TextSecureProtos; import org.whispersystems.textsecure.internal.util.Util; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; public class DeviceContactsOutputStream { @@ -25,7 +26,16 @@ public class DeviceContactsOutputStream { private void writeAvatarImage(DeviceContact contact) throws IOException { 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(); avatarBuilder.setContentType(contact.getAvatar().get().getContentType()); avatarBuilder.setLength(contact.getAvatar().get().getLength()); + contactDetails.setAvatar(avatarBuilder); } byte[] serializedContactDetails = contactDetails.build().toByteArray(); diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceInfo.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceInfo.java new file mode 100644 index 0000000000..6bfec3910e --- /dev/null +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceInfo.java @@ -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; + } +} diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/RequestMessage.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/RequestMessage.java new file mode 100644 index 0000000000..c2e65b0490 --- /dev/null +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/RequestMessage.java @@ -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; + } +} diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/TextSecureSyncMessage.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/TextSecureSyncMessage.java index c0f5e78c0c..fcc4d477f2 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/TextSecureSyncMessage.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/TextSecureSyncMessage.java @@ -9,29 +9,41 @@ public class TextSecureSyncMessage { private final Optional sent; private final Optional contacts; private final Optional group; + private final Optional request; public TextSecureSyncMessage() { this.sent = Optional.absent(); this.contacts = Optional.absent(); this.group = Optional.absent(); + this.request = Optional.absent(); } public TextSecureSyncMessage(SentTranscriptMessage sent) { this.sent = Optional.of(sent); this.contacts = Optional.absent(); this.group = Optional.absent(); + this.request = Optional.absent(); } public TextSecureSyncMessage(TextSecureAttachment contacts) { this.contacts = Optional.of(contacts); this.sent = Optional.absent(); this.group = Optional.absent(); + this.request = Optional.absent(); } public TextSecureSyncMessage(TextSecureGroup group) { this.group = Optional.of(group); this.sent = 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 getSent() { @@ -46,4 +58,8 @@ public class TextSecureSyncMessage { return contacts; } + public Optional getRequest() { + return request; + } + } diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceInfoList.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceInfoList.java new file mode 100644 index 0000000000..e8ac1ece0c --- /dev/null +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceInfoList.java @@ -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 devices; + + public DeviceInfoList() {} + + public List getDevices() { + return devices; + } +} diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimit.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimit.java new file mode 100644 index 0000000000..cc83e7373f --- /dev/null +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimit.java @@ -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; + } +} diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimitExceededException.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimitExceededException.java new file mode 100644 index 0000000000..9f2c3461da --- /dev/null +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/DeviceLimitExceededException.java @@ -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(); + } +} diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java index eafd850048..d62c9b7b72 100644 --- a/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java @@ -27,6 +27,7 @@ import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.util.guava.Optional; 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.TextSecureAddress; 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_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_VERIFY_PATH = "/v1/directory/%s"; @@ -126,6 +128,15 @@ public class PushServiceSocket { return JsonUtil.fromJson(responseText, DeviceCode.class).getVerificationCode(); } + public List 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 { makeRequest(String.format(PROVISIONING_MESSAGE_PATH, destination), "PUT", JsonUtil.toJson(new ProvisioningMessage(Base64.encodeBytes(body)))); @@ -483,6 +494,13 @@ public class PushServiceSocket { throw new PushNetworkException(e); } 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: throw new ExpectationFailedException(); } diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/TextSecureProtos.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/TextSecureProtos.java index 05d96f2590..7533221050 100644 --- a/java/src/main/java/org/whispersystems/textsecure/internal/push/TextSecureProtos.java +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/TextSecureProtos.java @@ -3150,6 +3150,20 @@ public final class TextSecureProtos { * optional .textsecure.SyncMessage.Group group = 3; */ org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.GroupOrBuilder getGroupOrBuilder(); + + // optional .textsecure.SyncMessage.Request request = 4; + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + boolean hasRequest(); + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest(); + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder(); } /** * Protobuf type {@code textsecure.SyncMessage} @@ -3241,6 +3255,19 @@ public final class TextSecureProtos { bitField0_ |= 0x00000004; 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) { @@ -5038,6 +5065,493 @@ public final class TextSecureProtos { // @@protoc_insertion_point(class_scope:textsecure.SyncMessage.Group) } + public interface RequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional .textsecure.SyncMessage.Request.Type type = 1; + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + boolean hasType(); + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + 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 PARSER = + new com.google.protobuf.AbstractParser() { + 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 getParserForType() { + return PARSER; + } + + /** + * Protobuf enum {@code textsecure.SyncMessage.Request.Type} + */ + public enum Type + implements com.google.protobuf.ProtocolMessageEnum { + /** + * UNKNOWN = 0; + */ + UNKNOWN(0, 0), + /** + * CONTACTS = 1; + */ + CONTACTS(1, 1), + ; + + /** + * UNKNOWN = 0; + */ + public static final int UNKNOWN_VALUE = 0; + /** + * CONTACTS = 1; + */ + 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 + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + 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_; + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + 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 + 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; + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Type getType() { + return type_; + } + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + 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; + } + /** + * optional .textsecure.SyncMessage.Request.Type type = 1; + */ + 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_; // optional .textsecure.SyncMessage.Sent sent = 1; public static final int SENT_FIELD_NUMBER = 1; @@ -5105,10 +5619,33 @@ public final class TextSecureProtos { 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_; + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public boolean hasRequest() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest() { + return request_; + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder() { + return request_; + } + private void initFields() { sent_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Sent.getDefaultInstance(); contacts_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Contacts.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; public final boolean isInitialized() { @@ -5131,6 +5668,9 @@ public final class TextSecureProtos { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeMessage(3, group_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(4, request_); + } getUnknownFields().writeTo(output); } @@ -5152,6 +5692,10 @@ public final class TextSecureProtos { size += com.google.protobuf.CodedOutputStream .computeMessageSize(3, group_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, request_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -5263,6 +5807,7 @@ public final class TextSecureProtos { getSentFieldBuilder(); getContactsFieldBuilder(); getGroupFieldBuilder(); + getRequestFieldBuilder(); } } private static Builder create() { @@ -5289,6 +5834,12 @@ public final class TextSecureProtos { groupBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000004); + if (requestBuilder_ == null) { + request_ = org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.getDefaultInstance(); + } else { + requestBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -5341,6 +5892,14 @@ public final class TextSecureProtos { } else { 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_; onBuilt(); return result; @@ -5366,6 +5925,9 @@ public final class TextSecureProtos { if (other.hasGroup()) { mergeGroup(other.getGroup()); } + if (other.hasRequest()) { + mergeRequest(other.getRequest()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -5744,6 +6306,123 @@ public final class TextSecureProtos { 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_; + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public boolean hasRequest() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request getRequest() { + if (requestBuilder_ == null) { + return request_; + } else { + return requestBuilder_.getMessage(); + } + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + 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; + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + 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; + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + 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; + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + 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; + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.Request.Builder getRequestBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getRequestFieldBuilder().getBuilder(); + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + public org.whispersystems.textsecure.internal.push.TextSecureProtos.SyncMessage.RequestOrBuilder getRequestOrBuilder() { + if (requestBuilder_ != null) { + return requestBuilder_.getMessageOrBuilder(); + } else { + return request_; + } + } + /** + * optional .textsecure.SyncMessage.Request request = 4; + */ + 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) } @@ -8919,6 +9598,11 @@ public final class TextSecureProtos { private static com.google.protobuf.GeneratedMessage.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 internal_static_textsecure_AttachmentPointer_descriptor; 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." + "textsecure.AttachmentPointer\022\'\n\005group\030\003 " + "\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" + "ssage.Sent\0222\n\010contacts\030\002 \001(\0132 .textsecur" + "e.SyncMessage.Contacts\022,\n\005group\030\003 \001(\0132\035." + - "textsecure.SyncMessage.Group\032X\n\004Sent\022\023\n\013" + - "destination\030\001 \001(\t\022\021\n\ttimestamp\030\002 \001(\004\022(\n\007" + - "message\030\003 \001(\0132\027.textsecure.DataMessage\0327", - "\n\010Contacts\022+\n\004blob\030\001 \001(\0132\035.textsecure.At" + - "tachmentPointer\0320\n\005Group\022\'\n\005group\030\001 \001(\0132" + - "\030.textsecure.GroupContext\"A\n\021AttachmentP" + - "ointer\022\n\n\002id\030\001 \001(\006\022\023\n\013contentType\030\002 \001(\t\022" + - "\013\n\003key\030\003 \001(\014\"\315\001\n\014GroupContext\022\n\n\002id\030\001 \001(" + - "\014\022+\n\004type\030\002 \001(\0162\035.textsecure.GroupContex" + - "t.Type\022\014\n\004name\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\022-\n" + - "\006avatar\030\005 \001(\0132\035.textsecure.AttachmentPoi" + - "nter\"6\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n" + - "\007DELIVER\020\002\022\010\n\004QUIT\020\003\"\220\001\n\016ContactDetails\022", - "\016\n\006number\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\0221\n\006avatar\030" + - "\003 \001(\0132!.textsecure.ContactDetails.Avatar" + - "\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006lengt" + - "h\030\002 \001(\004B?\n+org.whispersystems.textsecure" + - ".internal.pushB\020TextSecureProtos" + "textsecure.SyncMessage.Group\0220\n\007request\030" + + "\004 \001(\0132\037.textsecure.SyncMessage.Request\032X" + + "\n\004Sent\022\023\n\013destination\030\001 \001(\t\022\021\n\ttimestamp", + "\030\002 \001(\004\022(\n\007message\030\003 \001(\0132\027.textsecure.Dat" + + "aMessage\0327\n\010Contacts\022+\n\004blob\030\001 \001(\0132\035.tex" + + "tsecure.AttachmentPointer\0320\n\005Group\022\'\n\005gr" + + "oup\030\001 \001(\0132\030.textsecure.GroupContext\032`\n\007R" + + "equest\0222\n\004type\030\001 \001(\0162$.textsecure.SyncMe" + + "ssage.Request.Type\"!\n\004Type\022\013\n\007UNKNOWN\020\000\022" + + "\014\n\010CONTACTS\020\001\"A\n\021AttachmentPointer\022\n\n\002id" + + "\030\001 \001(\006\022\023\n\013contentType\030\002 \001(\t\022\013\n\003key\030\003 \001(\014" + + "\"\315\001\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022+\n\004type\030\002 " + + "\001(\0162\035.textsecure.GroupContext.Type\022\014\n\004na", + "me\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\022-\n\006avatar\030\005 \001(" + + "\0132\035.textsecure.AttachmentPointer\"6\n\004Type" + + "\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010" + + "\n\004QUIT\020\003\"\220\001\n\016ContactDetails\022\016\n\006number\030\001 " + + "\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 = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -9012,7 +9700,7 @@ public final class TextSecureProtos { internal_static_textsecure_SyncMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( 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_descriptor.getNestedTypes().get(0); internal_static_textsecure_SyncMessage_Sent_fieldAccessorTable = new @@ -9031,6 +9719,12 @@ public final class TextSecureProtos { com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_textsecure_SyncMessage_Group_descriptor, 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 = getDescriptor().getMessageTypes().get(4); internal_static_textsecure_AttachmentPointer_fieldAccessorTable = new diff --git a/protobuf/TextSecure.proto b/protobuf/TextSecure.proto index 0f86b7c731..4b6077115f 100644 --- a/protobuf/TextSecure.proto +++ b/protobuf/TextSecure.proto @@ -52,9 +52,19 @@ message SyncMessage { optional GroupContext group = 1; } + message Request { + enum Type { + UNKNOWN = 0; + CONTACTS = 1; + } + + optional Type type = 1; + } + optional Sent sent = 1; optional Contacts contacts = 2; optional Group group = 3; + optional Request request = 4; } message AttachmentPointer {