Sync Groups with Desktop

// FREEBIE
pull/1/head
Michael Kirk 9 years ago
parent 36d3691c74
commit 69da0b3c25

@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
[sentBuilder setDestination:self.message.recipientIdentifier];
[sentBuilder setMessage:[self.message buildDataMessage]];
[syncMessageBuilder setSent:[sentBuilder build]];
[syncMessageBuilder setSentBuilder:sentBuilder];
return [syncMessageBuilder build];
}

@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
{
NSAssert(NO, @"buildSyncMessage must be overridden in suclass");
NSAssert(NO, @"buildSyncMessage must be overridden in subclass");
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
return [syncMessageBuilder build];
@ -28,7 +28,6 @@ NS_ASSUME_NONNULL_BEGIN
return [[contentBuilder build] data];
}
@end
NS_ASSUME_NONNULL_END

@ -31,36 +31,18 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// no-op
// There's no need to save this message, since it's not displayed to the user.
// Furthermore if we did save it, we probably don't want to save the conctactsManager property.
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
{
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
OWSSignalServiceProtosSyncMessageContactsBuilder *contactsBuilder =
[OWSSignalServiceProtosSyncMessageContactsBuilder new];
[syncMessageBuilder setContactsBuilder:contactsBuilder];
if (self.attachmentIds.count != 1) {
DDLogError(@"expected sync contact message to have exactly one attachment, but found %lu",
(unsigned long)self.attachmentIds.count);
}
TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentIds[0]];
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentBuilder =
[OWSSignalServiceProtosAttachmentPointerBuilder new];
[attachmentBuilder setId:[attachment.identifier unsignedLongLongValue]];
[attachmentBuilder setContentType:attachment.contentType];
[attachmentBuilder setKey:attachment.encryptionKey];
OWSSignalServiceProtosSyncMessageContactsBuilder *contactsBuilder =
[OWSSignalServiceProtosSyncMessageContactsBuilder new];
[contactsBuilder setBlobBuilder:attachmentBuilder];
[syncMessageBuilder setContacts:[contactsBuilder build]];
[contactsBuilder setBlobBuilder:[self attachmentBuilderForAttachmentId:self.attachmentIds[0]]];
return [syncMessageBuilder build];
}
@ -88,9 +70,8 @@ NS_ASSUME_NONNULL_BEGIN
[avatarBuilder setContentType:@"image/png"];
avatarPng = UIImagePNGRepresentation(contact.image);
// TODO check datasize and safely cast to int
[avatarBuilder setLength:(uint32_t)avatarPng.length];
[contactBuilder setAvatar:[avatarBuilder build]];
[contactBuilder setAvatarBuilder:avatarBuilder];
}
NSData *contactData = [[contactBuilder build] data];

@ -1,5 +1,7 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSOutgoingSyncMessage.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSSyncGroupsMessage : OWSOutgoingSyncMessage

@ -1,12 +1,21 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSSyncGroupsMessage.h"
#import "NSDate+millisecondTimeStamp.h"
#import "OWSSignalServiceProtos.pb.h"
#import "TSAttachment.h"
#import "TSGroupModel.h"
#import "TSGroupThread.h"
NS_ASSUME_NONNULL_BEGIN
@implementation OWSSyncGroupsMessage
- (instancetype)init
{
return [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:nil messageBody:nil attachmentIds:@[]];
}
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// no-op
@ -18,25 +27,15 @@ NS_ASSUME_NONNULL_BEGIN
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
{
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
OWSSignalServiceProtosSyncMessageGroupsBuilder *groupsBuilder =
[OWSSignalServiceProtosSyncMessageGroupsBuilder new];
[syncMessageBuilder setGroupsBuilder:groupsBuilder];
if (self.attachmentIds.count != 1) {
DDLogError(@"expected sync contact message to have exactly one attachment, but found %lu",
DDLogError(@"expected sync groups message to have exactly one attachment, but found %lu",
(unsigned long)self.attachmentIds.count);
}
TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentIds[0]];
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentBuilder =
[OWSSignalServiceProtosAttachmentPointerBuilder new];
[attachmentBuilder setId:[attachment.identifier unsignedLongLongValue]];
[attachmentBuilder setContentType:attachment.contentType];
[attachmentBuilder setKey:attachment.encryptionKey];
OWSSignalServiceProtosSyncMessageContactsBuilder *contactsBuilder =
[OWSSignalServiceProtosSyncMessageContactsBuilder new];
[contactsBuilder setBlobBuilder:attachmentBuilder];
[syncMessageBuilder setContacts:[contactsBuilder build]];
[groupsBuilder setBlobBuilder:[self attachmentBuilderForAttachmentId:self.attachmentIds[0]]];
return [syncMessageBuilder build];
}
@ -50,35 +49,39 @@ NS_ASSUME_NONNULL_BEGIN
[fileOutputStream open];
PBCodedOutputStream *outputStream = [PBCodedOutputStream streamWithOutputStream:fileOutputStream];
DDLogInfo(@"Writing contacts data to %@", fileURL);
for (Contact *contact in self.contactsManager.signalContacts) {
OWSSignalServiceProtosContactDetailsBuilder *contactBuilder = [OWSSignalServiceProtosContactDetailsBuilder new];
[contactBuilder setName:contact.fullName];
[contactBuilder setNumber:contact.textSecureIdentifiers.firstObject];
DDLogInfo(@"Writing groups data to %@", fileURL);
[TSGroupThread enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) {
if (![obj isKindOfClass:[TSGroupThread class]]) {
DDLogError(@"Unexpected class in group collection: %@", obj);
return;
}
TSGroupModel *group = ((TSGroupThread *)obj).groupModel;
OWSSignalServiceProtosGroupDetailsBuilder *groupBuilder = [OWSSignalServiceProtosGroupDetailsBuilder new];
[groupBuilder setId:group.groupId];
[groupBuilder setName:group.groupName];
[groupBuilder setMembersArray:group.groupMemberIds];
NSData *avatarPng;
if (contact.image) {
OWSSignalServiceProtosContactDetailsAvatarBuilder *avatarBuilder =
[OWSSignalServiceProtosContactDetailsAvatarBuilder new];
if (group.groupImage) {
OWSSignalServiceProtosGroupDetailsAvatarBuilder *avatarBuilder =
[OWSSignalServiceProtosGroupDetailsAvatarBuilder new];
[avatarBuilder setContentType:@"image/png"];
avatarPng = UIImagePNGRepresentation(contact.image);
// TODO check datasize and safely cast to int
avatarPng = UIImagePNGRepresentation(group.groupImage);
[avatarBuilder setLength:(uint32_t)avatarPng.length];
[contactBuilder setAvatar:[avatarBuilder build]];
[groupBuilder setAvatarBuilder:avatarBuilder];
}
NSData *contactData = [[contactBuilder build] data];
NSData *groupData = [[groupBuilder build] data];
uint32_t groupDataLength = (uint32_t)groupData.length;
[outputStream writeRawVarint32:groupDataLength];
[outputStream writeRawData:groupData];
uint32_t contactDataLength = (uint32_t)contactData.length;
[outputStream writeRawVarint32:contactDataLength];
[outputStream writeRawData:contactData];
if (contact.image) {
if (avatarPng) {
[outputStream writeRawData:avatarPng];
}
}
}];
[outputStream flush];
[fileOutputStream close];

@ -5,7 +5,7 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosDataMessage;
@class OWSSignalServiceProtosAttachmentPointerBuilder;
@interface TSOutgoingMessage : TSMessage
@ -36,6 +36,15 @@ typedef NS_ENUM(NSInteger, TSOutgoingMessageState) {
*/
- (BOOL)shouldSyncTranscript;
/**
* @param attachmentStream
* Containing the meta data used when populating the attachment proto
*
* @return
* An attachment builder suitable for including in various container protobuf builders
*/
- (OWSSignalServiceProtosAttachmentPointerBuilder *)attachmentBuilderForAttachmentId:(NSString *)attachmentId;
@end
NS_ASSUME_NONNULL_END

@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSignalServiceProtosDataMessageBuilder *builder = [OWSSignalServiceProtosDataMessageBuilder new];
[builder setBody:self.body];
BOOL processAttachments = YES;
BOOL attachmentWasGroupAvatar = NO;
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *gThread = (TSGroupThread *)thread;
OWSSignalServiceProtosGroupContextBuilder *groupBuilder = [OWSSignalServiceProtosGroupContextBuilder new];
@ -56,19 +56,11 @@ NS_ASSUME_NONNULL_BEGIN
break;
case TSGroupMessageUpdate:
case TSGroupMessageNew: {
if (gThread.groupModel.groupImage != nil && [self.attachmentIds count] == 1) {
id dbObject = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentIds[0]];
if ([dbObject isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *attachment = (TSAttachmentStream *)dbObject;
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentbuilder =
[OWSSignalServiceProtosAttachmentPointerBuilder new];
[attachmentbuilder setId:[attachment.identifier unsignedLongLongValue]];
[attachmentbuilder setContentType:attachment.contentType];
[attachmentbuilder setKey:attachment.encryptionKey];
[groupBuilder setAvatar:[attachmentbuilder build]];
processAttachments = NO;
}
if (gThread.groupModel.groupImage != nil && self.attachmentIds.count == 1) {
attachmentWasGroupAvatar = YES;
[groupBuilder setAvatarBuilder:[self attachmentBuilderForAttachmentId:self.attachmentIds[0]]];
}
[groupBuilder setMembersArray:gThread.groupModel.groupMemberIds];
[groupBuilder setName:gThread.groupModel.groupName];
[groupBuilder setType:OWSSignalServiceProtosGroupContextTypeUpdate];
@ -81,22 +73,12 @@ NS_ASSUME_NONNULL_BEGIN
[groupBuilder setId:gThread.groupModel.groupId];
[builder setGroup:groupBuilder.build];
}
if (processAttachments) {
if (!attachmentWasGroupAvatar) {
NSMutableArray *attachments = [NSMutableArray new];
for (NSString *attachmentId in self.attachmentIds) {
id dbObject = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId];
if ([dbObject isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *attachment = (TSAttachmentStream *)dbObject;
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentbuilder =
[OWSSignalServiceProtosAttachmentPointerBuilder new];
[attachmentbuilder setId:[attachment.identifier unsignedLongLongValue]];
[attachmentbuilder setContentType:attachment.contentType];
[attachmentbuilder setKey:attachment.encryptionKey];
[attachments addObject:[attachmentbuilder build]];
}
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentBuilder =
[self attachmentBuilderForAttachmentId:attachmentId];
[attachments addObject:[attachmentBuilder build]];
}
[builder setAttachmentsArray:attachments];
}
@ -113,6 +95,23 @@ NS_ASSUME_NONNULL_BEGIN
return !self.hasSyncedTranscript;
}
- (OWSSignalServiceProtosAttachmentPointerBuilder *)attachmentBuilderForAttachmentId:(NSString *)attachmentId
{
TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
DDLogError(@"Unexpected type for attachment builder: %@", attachment);
return nil;
}
TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment;
OWSSignalServiceProtosAttachmentPointerBuilder *builder = [OWSSignalServiceProtosAttachmentPointerBuilder new];
[builder setId:[attachmentStream.identifier unsignedLongLongValue]];
[builder setContentType:attachmentStream.contentType];
[builder setKey:attachmentStream.encryptionKey];
return builder;
}
@end
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save