diff --git a/protobuf/OWSSignalServiceProtos.proto b/protobuf/OWSSignalServiceProtos.proto index 94b20de0a..814990829 100644 --- a/protobuf/OWSSignalServiceProtos.proto +++ b/protobuf/OWSSignalServiceProtos.proto @@ -133,13 +133,18 @@ message SyncMessage { } message AttachmentPointer { - optional fixed64 id = 1; - optional string contentType = 2; - optional bytes key = 3; - optional uint32 size = 4; - optional bytes thumbnail = 5; - optional bytes digest = 6; - optional string fileName = 7; + enum Flags { + VOICE_MESSAGE = 1; + } + + optional fixed64 id = 1; + optional string contentType = 2; + optional bytes key = 3; + optional uint32 size = 4; + optional bytes thumbnail = 5; + optional bytes digest = 6; + optional string fileName = 7; + optional uint32 flags = 8; } message GroupContext { diff --git a/src/Messages/Attachments/OWSAttachmentsProcessor.m b/src/Messages/Attachments/OWSAttachmentsProcessor.m index 05a526951..1cd27dc0e 100644 --- a/src/Messages/Attachments/OWSAttachmentsProcessor.m +++ b/src/Messages/Attachments/OWSAttachmentsProcessor.m @@ -79,12 +79,21 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f; // digest will be empty for old clients. NSData *digest = attachmentProto.hasDigest ? attachmentProto.digest : nil; + TSAttachmentType attachmentType = TSAttachmentTypeDefault; + if ([attachmentProto hasFlags]) { + UInt32 flags = attachmentProto.flags; + if ((flags & (UInt32)OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage) > 0) { + attachmentType = TSAttachmentTypeVoiceMessage; + } + } + TSAttachmentPointer *pointer = [[TSAttachmentPointer alloc] initWithServerId:attachmentProto.id key:attachmentProto.key digest:digest contentType:attachmentProto.contentType relay:relay - filename:attachmentProto.fileName]; + filename:attachmentProto.fileName + attachmentType:attachmentType]; [attachmentIds addObject:pointer.uniqueId]; diff --git a/src/Messages/Attachments/TSAttachment.h b/src/Messages/Attachments/TSAttachment.h index 9fd8d3f29..d26bc74c4 100644 --- a/src/Messages/Attachments/TSAttachment.h +++ b/src/Messages/Attachments/TSAttachment.h @@ -6,6 +6,11 @@ NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSUInteger, TSAttachmentType) { + TSAttachmentTypeDefault = 0, + TSAttachmentTypeVoiceMessage = 1, +}; + @interface TSAttachment : TSYapDatabaseObject { @protected @@ -24,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSString *contentType; @property (atomic, readwrite) BOOL isDownloaded; +@property (nonatomic) TSAttachmentType attachmentType; // This constructor is used for new instances of TSAttachmentPointer, // i.e. undownloaded incoming attachments. @@ -43,6 +49,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)upgradeFromAttachmentSchemaVersion:(NSUInteger)attachmentSchemaVersion; +- (BOOL)isVoiceMessage; + @end NS_ASSUME_NONNULL_END diff --git a/src/Messages/Attachments/TSAttachment.m b/src/Messages/Attachments/TSAttachment.m index cd92bbf38..53f3f830b 100644 --- a/src/Messages/Attachments/TSAttachment.m +++ b/src/Messages/Attachments/TSAttachment.m @@ -110,6 +110,11 @@ NSUInteger const TSAttachmentSchemaVersion = 3; return attachmentString; } +- (BOOL)isVoiceMessage +{ + return self.attachmentType == TSAttachmentTypeVoiceMessage; +} + #pragma mark - Logging + (NSString *)tag diff --git a/src/Messages/Attachments/TSAttachmentPointer.h b/src/Messages/Attachments/TSAttachmentPointer.h index 80201766d..106a1ad88 100644 --- a/src/Messages/Attachments/TSAttachmentPointer.h +++ b/src/Messages/Attachments/TSAttachmentPointer.h @@ -24,7 +24,8 @@ typedef NS_ENUM(NSUInteger, TSAttachmentPointerState) { digest:(nullable NSData *)digest contentType:(NSString *)contentType relay:(NSString *)relay - filename:(nullable NSString *)filename NS_DESIGNATED_INITIALIZER; + filename:(nullable NSString *)filename + attachmentType:(TSAttachmentType)attachmentType NS_DESIGNATED_INITIALIZER; @property (nonatomic, readonly) NSString *relay; @property (nonatomic, readonly, nullable) NSString *filename; diff --git a/src/Messages/Attachments/TSAttachmentPointer.m b/src/Messages/Attachments/TSAttachmentPointer.m index 7097a204a..a2998a5a5 100644 --- a/src/Messages/Attachments/TSAttachmentPointer.m +++ b/src/Messages/Attachments/TSAttachmentPointer.m @@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN contentType:(NSString *)contentType relay:(NSString *)relay filename:(nullable NSString *)filename + attachmentType:(TSAttachmentType)attachmentType { self = [super initWithServerId:serverId encryptionKey:key contentType:contentType]; if (!self) { @@ -41,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN _state = TSAttachmentPointerStateEnqueued; _relay = relay; _filename = filename; + self.attachmentType = attachmentType; return self; } diff --git a/src/Messages/Attachments/TSAttachmentStream.m b/src/Messages/Attachments/TSAttachmentStream.m index d29a83479..9c6799b4a 100644 --- a/src/Messages/Attachments/TSAttachmentStream.m +++ b/src/Messages/Attachments/TSAttachmentStream.m @@ -44,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN // attachments which don't need to be uploaded. _isUploaded = YES; _filename = pointer.filename; + self.attachmentType = pointer.attachmentType; return self; } diff --git a/src/Messages/Interactions/TSOutgoingMessage.h b/src/Messages/Interactions/TSOutgoingMessage.h index af505589a..b711bcd0d 100644 --- a/src/Messages/Interactions/TSOutgoingMessage.h +++ b/src/Messages/Interactions/TSOutgoingMessage.h @@ -57,6 +57,11 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { attachmentIds:(NSMutableArray *)attachmentIds expiresInSeconds:(uint32_t)expiresInSeconds; +- (instancetype)initWithTimestamp:(uint64_t)timestamp + inThread:(nullable TSThread *)thread + isVoiceMessage:(BOOL)isVoiceMessage + expiresInSeconds:(uint32_t)expiresInSeconds; + - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread messageBody:(nullable NSString *)body @@ -95,6 +100,8 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { */ @property (nonatomic, readonly) BOOL isLegacyMessage; +@property (nonatomic, readonly) BOOL isVoiceMessage; + /** * Signal Identifier (e.g. e164 number) or nil if in a group thread. */ diff --git a/src/Messages/Interactions/TSOutgoingMessage.m b/src/Messages/Interactions/TSOutgoingMessage.m index a16995468..471f63071 100644 --- a/src/Messages/Interactions/TSOutgoingMessage.m +++ b/src/Messages/Interactions/TSOutgoingMessage.m @@ -22,6 +22,7 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec @property (atomic) NSString *customMessage; @property (atomic) NSString *mostRecentFailureText; @property (atomic) BOOL wasDelivered; + // For outgoing, non-legacy group messages sent from this client, this // contains the list of recipients to whom the message has been sent. // @@ -110,6 +111,24 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec expireStartedAt:0]; } +- (instancetype)initWithTimestamp:(uint64_t)timestamp + inThread:(nullable TSThread *)thread + isVoiceMessage:(BOOL)isVoiceMessage + expiresInSeconds:(uint32_t)expiresInSeconds +{ + self = [self initWithTimestamp:timestamp + inThread:thread + messageBody:nil + attachmentIds:[NSMutableArray new] + expiresInSeconds:expiresInSeconds + expireStartedAt:0]; + if (self) { + _isVoiceMessage = isVoiceMessage; + } + + return self; +} + - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread messageBody:(nullable NSString *)body @@ -452,7 +471,7 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec [builder setFileName:filename]; [builder setKey:attachmentStream.encryptionKey]; [builder setDigest:attachmentStream.digest]; - + [builder setFlags:(self.isVoiceMessage ? OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage : 0)]; return [builder build]; } diff --git a/src/Messages/OWSSignalServiceProtos.pb.h b/src/Messages/OWSSignalServiceProtos.pb.h index 9ef8c1214..8db11c83b 100644 --- a/src/Messages/OWSSignalServiceProtos.pb.h +++ b/src/Messages/OWSSignalServiceProtos.pb.h @@ -1,4 +1,6 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import @@ -123,6 +125,13 @@ typedef NS_ENUM(SInt32, OWSSignalServiceProtosSyncMessageRequestType) { BOOL OWSSignalServiceProtosSyncMessageRequestTypeIsValidValue(OWSSignalServiceProtosSyncMessageRequestType value); NSString *NSStringFromOWSSignalServiceProtosSyncMessageRequestType(OWSSignalServiceProtosSyncMessageRequestType value); +typedef NS_ENUM(SInt32, OWSSignalServiceProtosAttachmentPointerFlags) { + OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage = 1, +}; + +BOOL OWSSignalServiceProtosAttachmentPointerFlagsIsValidValue(OWSSignalServiceProtosAttachmentPointerFlags value); +NSString *NSStringFromOWSSignalServiceProtosAttachmentPointerFlags(OWSSignalServiceProtosAttachmentPointerFlags value); + typedef NS_ENUM(SInt32, OWSSignalServiceProtosGroupContextType) { OWSSignalServiceProtosGroupContextTypeUnknown = 0, OWSSignalServiceProtosGroupContextTypeUpdate = 1, @@ -1290,6 +1299,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro #define AttachmentPointer_thumbnail @"thumbnail" #define AttachmentPointer_digest @"digest" #define AttachmentPointer_fileName @"fileName" +#define AttachmentPointer_flags @"flags" @interface OWSSignalServiceProtosAttachmentPointer : PBGeneratedMessage { @private BOOL hasId_:1; @@ -1299,6 +1309,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro BOOL hasThumbnail_:1; BOOL hasDigest_:1; BOOL hasSize_:1; + BOOL hasFlags_ : 1; UInt64 id; NSString* contentType; NSString* fileName; @@ -1306,6 +1317,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro NSData* thumbnail; NSData* digest; UInt32 size; + UInt32 flags; } - (BOOL) hasId; - (BOOL) hasContentType; @@ -1314,6 +1326,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro - (BOOL) hasThumbnail; - (BOOL) hasDigest; - (BOOL) hasFileName; +- (BOOL)hasFlags; @property (readonly) UInt64 id; @property (readonly, strong) NSString* contentType; @property (readonly, strong) NSData* key; @@ -1321,6 +1334,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro @property (readonly, strong) NSData* thumbnail; @property (readonly, strong) NSData* digest; @property (readonly, strong) NSString* fileName; +@property (readonly) UInt32 flags; + (instancetype) defaultInstance; - (instancetype) defaultInstance; @@ -1391,6 +1405,11 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro - (NSString*) fileName; - (OWSSignalServiceProtosAttachmentPointerBuilder*) setFileName:(NSString*) value; - (OWSSignalServiceProtosAttachmentPointerBuilder*) clearFileName; + +- (BOOL)hasFlags; +- (UInt32)flags; +- (OWSSignalServiceProtosAttachmentPointerBuilder *)setFlags:(UInt32)value; +- (OWSSignalServiceProtosAttachmentPointerBuilder *)clearFlags; @end #define GroupContext_id @"id" diff --git a/src/Messages/OWSSignalServiceProtos.pb.m b/src/Messages/OWSSignalServiceProtos.pb.m index 5c0598aa2..3325006de 100644 --- a/src/Messages/OWSSignalServiceProtos.pb.m +++ b/src/Messages/OWSSignalServiceProtos.pb.m @@ -1,4 +1,6 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "OWSSignalServiceProtos.pb.h" // @@protoc_insertion_point(imports) @@ -5375,6 +5377,7 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM @property (strong) NSData* thumbnail; @property (strong) NSData* digest; @property (strong) NSString* fileName; +@property UInt32 flags; @end @implementation OWSSignalServiceProtosAttachmentPointer @@ -5428,6 +5431,15 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM hasFileName_ = !!_value_; } @synthesize fileName; +- (BOOL)hasFlags +{ + return !!hasFlags_; +} +- (void)setHasFlags:(BOOL)_value_ +{ + hasFlags_ = !!_value_; +} +@synthesize flags; - (instancetype) init { if ((self = [super init])) { self.id = 0L; @@ -5437,6 +5449,7 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM self.thumbnail = [NSData data]; self.digest = [NSData data]; self.fileName = @""; + self.flags = 0; } return self; } @@ -5477,6 +5490,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (self.hasFileName) { [output writeString:7 value:self.fileName]; } + if (self.hasFlags) { + [output writeUInt32:8 value:self.flags]; + } [self.unknownFields writeToCodedOutputStream:output]; } - (SInt32) serializedSize { @@ -5507,6 +5523,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (self.hasFileName) { size_ += computeStringSize(7, self.fileName); } + if (self.hasFlags) { + size_ += computeUInt32Size(8, self.flags); + } size_ += self.unknownFields.serializedSize; memoizedSerializedSize = size_; return size_; @@ -5563,6 +5582,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (self.hasFileName) { [output appendFormat:@"%@%@: %@\n", indent, @"fileName", self.fileName]; } + if (self.hasFlags) { + [output appendFormat:@"%@%@: %@\n", indent, @"flags", [NSNumber numberWithInteger:self.flags]]; + } [self.unknownFields writeDescriptionTo:output withIndent:indent]; } - (void) storeInDictionary:(NSMutableDictionary *)dictionary { @@ -5587,6 +5609,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (self.hasFileName) { [dictionary setObject: self.fileName forKey: @"fileName"]; } + if (self.hasFlags) { + [dictionary setObject:[NSNumber numberWithInteger:self.flags] forKey:@"flags"]; + } [self.unknownFields storeInDictionary:dictionary]; } - (BOOL) isEqual:(id)other { @@ -5597,22 +5622,19 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt return NO; } OWSSignalServiceProtosAttachmentPointer *otherMessage = other; - return - self.hasId == otherMessage.hasId && - (!self.hasId || self.id == otherMessage.id) && - self.hasContentType == otherMessage.hasContentType && - (!self.hasContentType || [self.contentType isEqual:otherMessage.contentType]) && - self.hasKey == otherMessage.hasKey && - (!self.hasKey || [self.key isEqual:otherMessage.key]) && - self.hasSize == otherMessage.hasSize && - (!self.hasSize || self.size == otherMessage.size) && - self.hasThumbnail == otherMessage.hasThumbnail && - (!self.hasThumbnail || [self.thumbnail isEqual:otherMessage.thumbnail]) && - self.hasDigest == otherMessage.hasDigest && - (!self.hasDigest || [self.digest isEqual:otherMessage.digest]) && - self.hasFileName == otherMessage.hasFileName && - (!self.hasFileName || [self.fileName isEqual:otherMessage.fileName]) && - (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields])); + return self.hasId == otherMessage.hasId && (!self.hasId || self.id == otherMessage.id) + && self.hasContentType == otherMessage.hasContentType + && (!self.hasContentType || [self.contentType isEqual:otherMessage.contentType]) + && self.hasKey == otherMessage.hasKey && (!self.hasKey || [self.key isEqual:otherMessage.key]) + && self.hasSize == otherMessage.hasSize && (!self.hasSize || self.size == otherMessage.size) + && self.hasThumbnail == otherMessage.hasThumbnail + && (!self.hasThumbnail || [self.thumbnail isEqual:otherMessage.thumbnail]) + && self.hasDigest == otherMessage.hasDigest && (!self.hasDigest || [self.digest isEqual:otherMessage.digest]) + && self.hasFileName == otherMessage.hasFileName + && (!self.hasFileName || [self.fileName isEqual:otherMessage.fileName]) && self.hasFlags == otherMessage.hasFlags + && (!self.hasFlags || self.flags == otherMessage.flags) + && (self.unknownFields == otherMessage.unknownFields + || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields])); } - (NSUInteger) hash { __block NSUInteger hashCode = 7; @@ -5637,11 +5659,33 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (self.hasFileName) { hashCode = hashCode * 31 + [self.fileName hash]; } + if (self.hasFlags) { + hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.flags] hash]; + } hashCode = hashCode * 31 + [self.unknownFields hash]; return hashCode; } @end +BOOL OWSSignalServiceProtosAttachmentPointerFlagsIsValidValue(OWSSignalServiceProtosAttachmentPointerFlags value) +{ + switch (value) { + case OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage: + return YES; + default: + return NO; + } +} +NSString *NSStringFromOWSSignalServiceProtosAttachmentPointerFlags(OWSSignalServiceProtosAttachmentPointerFlags value) +{ + switch (value) { + case OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage: + return @"OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage"; + default: + return nil; + } +} + @interface OWSSignalServiceProtosAttachmentPointerBuilder() @property (strong) OWSSignalServiceProtosAttachmentPointer* resultAttachmentPointer; @end @@ -5701,6 +5745,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt if (other.hasFileName) { [self setFileName:other.fileName]; } + if (other.hasFlags) { + [self setFlags:other.flags]; + } [self mergeUnknownFields:other.unknownFields]; return self; } @@ -5750,6 +5797,10 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt [self setFileName:[input readString]]; break; } + case 64: { + [self setFlags:[input readUInt32]]; + break; + } } } } @@ -5865,6 +5916,26 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt resultAttachmentPointer.fileName = @""; return self; } +- (BOOL)hasFlags +{ + return resultAttachmentPointer.hasFlags; +} +- (UInt32)flags +{ + return resultAttachmentPointer.flags; +} +- (OWSSignalServiceProtosAttachmentPointerBuilder *)setFlags:(UInt32)value +{ + resultAttachmentPointer.hasFlags = YES; + resultAttachmentPointer.flags = value; + return self; +} +- (OWSSignalServiceProtosAttachmentPointerBuilder *)clearFlags +{ + resultAttachmentPointer.hasFlags = NO; + resultAttachmentPointer.flags = 0; + return self; +} @end @interface OWSSignalServiceProtosGroupContext ()