Use attachment pointers to restore attachments from backup.

pull/1/head
Matthew Chen 7 years ago
parent e72dafb08e
commit d76bdf3a58

@ -618,6 +618,11 @@ NS_ASSUME_NONNULL_BEGIN
return completion(NO); return completion(NO);
} }
if (![OWSFileSystem deleteFileIfExists:attachmentFilePath]) {
OWSLogError(@"Couldn't delete exist file at attachment path.");
return completion(NO);
}
NSError *error; NSError *error;
BOOL success = BOOL success =
[NSFileManager.defaultManager moveItemAtPath:decryptedFilePath toPath:attachmentFilePath error:&error]; [NSFileManager.defaultManager moveItemAtPath:decryptedFilePath toPath:attachmentFilePath error:&error];

@ -507,6 +507,17 @@ NS_ASSUME_NONNULL_BEGIN
TSYapDatabaseObject *entity = object; TSYapDatabaseObject *entity = object;
count++; count++;
if ([entity isKindOfClass:[TSAttachmentStream class]]) {
// Convert attachment streams to pointers,
// since we'll need to restore them.
TSAttachmentStream *attachmentStream
= (TSAttachmentStream *)entity;
TSAttachmentPointer *attachmentPointer =
[[TSAttachmentPointer alloc]
initForRestoreWithAttachmentStream:attachmentStream];
entity = attachmentPointer;
}
if (![exportStream writeObject:entity entityType:entityType]) { if (![exportStream writeObject:entity entityType:entityType]) {
*stop = YES; *stop = YES;
aborted = YES; aborted = YES;
@ -536,6 +547,7 @@ NS_ASSUME_NONNULL_BEGIN
[TSAttachment class], [TSAttachment class],
^(id object) { ^(id object) {
if (![object isKindOfClass:[TSAttachmentStream class]]) { if (![object isKindOfClass:[TSAttachmentStream class]]) {
// No need to backup the contents of attachment pointers.
return NO; return NO;
} }
TSAttachmentStream *attachmentStream = object; TSAttachmentStream *attachmentStream = object;

@ -6,6 +6,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class TSAttachmentPointer;
@class TSMessage; @class TSMessage;
typedef NS_ENUM(NSUInteger, TSAttachmentType) { typedef NS_ENUM(NSUInteger, TSAttachmentType) {
@ -64,10 +65,11 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) {
// This constructor is used for new instances of TSAttachmentPointer, // This constructor is used for new instances of TSAttachmentPointer,
// i.e. undownloaded restoring attachments. // i.e. undownloaded restoring attachments.
- (instancetype)initWithContentType:(NSString *)contentType - (instancetype)initWithUniqueId:(NSString *)uniqueId
sourceFilename:(nullable NSString *)sourceFilename contentType:(NSString *)contentType
caption:(nullable NSString *)caption sourceFilename:(nullable NSString *)sourceFilename
albumMessageId:(nullable NSString *)albumMessageId; caption:(nullable NSString *)caption
albumMessageId:(nullable NSString *)albumMessageId;
// This constructor is used for new instances of TSAttachmentStream // This constructor is used for new instances of TSAttachmentStream
// that represent new, un-uploaded outgoing attachments. // that represent new, un-uploaded outgoing attachments.
@ -79,7 +81,7 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) {
// This constructor is used for new instances of TSAttachmentStream // This constructor is used for new instances of TSAttachmentStream
// that represent downloaded incoming attachments. // that represent downloaded incoming attachments.
- (instancetype)initWithPointer:(TSAttachment *)pointer; - (instancetype)initWithPointer:(TSAttachmentPointer *)pointer;
- (nullable instancetype)initWithCoder:(NSCoder *)coder; - (nullable instancetype)initWithCoder:(NSCoder *)coder;

@ -4,6 +4,7 @@
#import "TSAttachment.h" #import "TSAttachment.h"
#import "MIMETypeUtil.h" #import "MIMETypeUtil.h"
#import "TSAttachmentPointer.h"
#import "TSMessage.h" #import "TSMessage.h"
#import <SignalCoreKit/NSString+SSK.h> #import <SignalCoreKit/NSString+SSK.h>
#import <SignalCoreKit/iOSVersions.h> #import <SignalCoreKit/iOSVersions.h>
@ -67,11 +68,13 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
// This constructor is used for new instances of TSAttachmentPointer, // This constructor is used for new instances of TSAttachmentPointer,
// i.e. undownloaded restoring attachments. // i.e. undownloaded restoring attachments.
- (instancetype)initWithContentType:(NSString *)contentType - (instancetype)initWithUniqueId:(NSString *)uniqueId
sourceFilename:(nullable NSString *)sourceFilename contentType:(NSString *)contentType
caption:(nullable NSString *)caption sourceFilename:(nullable NSString *)sourceFilename
albumMessageId:(nullable NSString *)albumMessageId caption:(nullable NSString *)caption
albumMessageId:(nullable NSString *)albumMessageId
{ {
OWSAssertDebug(uniqueId.length > 0);
if (contentType.length < 1) { if (contentType.length < 1) {
OWSLogWarn(@"incoming attachment has invalid content type"); OWSLogWarn(@"incoming attachment has invalid content type");
@ -79,7 +82,8 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
} }
OWSAssertDebug(contentType.length > 0); OWSAssertDebug(contentType.length > 0);
self = [super init]; // Once saved, this AttachmentStream will replace the AttachmentPointer in the attachments collection.
self = [super initWithUniqueId:uniqueId];
if (!self) { if (!self) {
return self; return self;
} }
@ -128,13 +132,15 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
// This constructor is used for new instances of TSAttachmentStream // This constructor is used for new instances of TSAttachmentStream
// that represent downloaded incoming attachments. // that represent downloaded incoming attachments.
- (instancetype)initWithPointer:(TSAttachment *)pointer - (instancetype)initWithPointer:(TSAttachmentPointer *)pointer
{ {
OWSAssertDebug(pointer.serverId > 0); if (!pointer.lazyRestoreFragment) {
OWSAssertDebug(pointer.encryptionKey.length > 0); OWSAssertDebug(pointer.serverId > 0);
if (pointer.byteCount <= 0) { OWSAssertDebug(pointer.encryptionKey.length > 0);
// This will fail with legacy iOS clients which don't upload attachment size. if (pointer.byteCount <= 0) {
OWSLogWarn(@"Missing pointer.byteCount for attachment with serverId: %lld", pointer.serverId); // This will fail with legacy iOS clients which don't upload attachment size.
OWSLogWarn(@"Missing pointer.byteCount for attachment with serverId: %lld", pointer.serverId);
}
} }
OWSAssertDebug(pointer.contentType.length > 0); OWSAssertDebug(pointer.contentType.length > 0);

@ -8,6 +8,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSBackupFragment; @class OWSBackupFragment;
@class SSKProtoAttachmentPointer; @class SSKProtoAttachmentPointer;
@class TSAttachmentStream;
@class TSMessage; @class TSMessage;
typedef NS_ENUM(NSUInteger, TSAttachmentPointerType) { typedef NS_ENUM(NSUInteger, TSAttachmentPointerType) {
@ -49,11 +50,7 @@ typedef NS_ENUM(NSUInteger, TSAttachmentPointerState) {
albumMessageId:(nullable NSString *)albumMessageId albumMessageId:(nullable NSString *)albumMessageId
attachmentType:(TSAttachmentType)attachmentType NS_DESIGNATED_INITIALIZER; attachmentType:(TSAttachmentType)attachmentType NS_DESIGNATED_INITIALIZER;
- (instancetype)initForRestoreWithContentType:(NSString *)contentType - (instancetype)initForRestoreWithAttachmentStream:(TSAttachmentStream *)attachmentStream NS_DESIGNATED_INITIALIZER;
sourceFilename:(nullable NSString *)sourceFilename
caption:(nullable NSString *)caption
albumMessageId:(nullable NSString *)albumMessageId
attachmentType:(TSAttachmentType)attachmentType NS_DESIGNATED_INITIALIZER;
+ (nullable TSAttachmentPointer *)attachmentPointerFromProto:(SSKProtoAttachmentPointer *)attachmentProto + (nullable TSAttachmentPointer *)attachmentPointerFromProto:(SSKProtoAttachmentPointer *)attachmentProto
albumMessage:(nullable TSMessage *)message; albumMessage:(nullable TSMessage *)message;

@ -4,6 +4,7 @@
#import "TSAttachmentPointer.h" #import "TSAttachmentPointer.h"
#import "OWSBackupFragment.h" #import "OWSBackupFragment.h"
#import "TSAttachmentStream.h"
#import <SignalServiceKit/MimeTypeUtil.h> #import <SignalServiceKit/MimeTypeUtil.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h> #import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
@ -71,22 +72,21 @@ NS_ASSUME_NONNULL_BEGIN
return self; return self;
} }
- (instancetype)initForRestoreWithContentType:(NSString *)contentType - (instancetype)initForRestoreWithAttachmentStream:(TSAttachmentStream *)attachmentStream
sourceFilename:(nullable NSString *)sourceFilename
caption:(nullable NSString *)caption
albumMessageId:(nullable NSString *)albumMessageId
attachmentType:(TSAttachmentType)attachmentType
{ {
self = [super initWithContentType:contentType OWSAssertDebug(attachmentStream);
sourceFilename:sourceFilename
caption:caption self = [super initWithUniqueId:attachmentStream.uniqueId
albumMessageId:albumMessageId]; contentType:attachmentStream.contentType
sourceFilename:attachmentStream.sourceFilename
caption:attachmentStream.caption
albumMessageId:attachmentStream.albumMessageId];
if (!self) { if (!self) {
return self; return self;
} }
_state = TSAttachmentPointerStateEnqueued; _state = TSAttachmentPointerStateEnqueued;
self.attachmentType = attachmentType; self.attachmentType = attachmentStream.attachmentType;
_pointerType = TSAttachmentPointerTypeRestoring; _pointerType = TSAttachmentPointerTypeRestoring;
return self; return self;

@ -566,7 +566,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
} }
} else { } else {
// Neither a group nor contact thread? This should never happen. // Neither a group nor contact thread? This should never happen.
OWSFailDebug(@"Unknown message type: %@", [message class]); OWSLogError(@"Unknown message type: %@", [message class]);
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError(); NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
[error setIsRetryable:NO]; [error setIsRetryable:NO];
*errorHandle = error; *errorHandle = error;

Loading…
Cancel
Save