Respond to CR.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 46f17a02cb
commit 993df25f3f

@ -59,8 +59,8 @@ NSString *const OWSReadReceiptsProcessorMarkedMessageAsReadNotification =
- (instancetype)initWithIncomingMessage:(TSIncomingMessage *)message storageManager:(TSStorageManager *)storageManager - (instancetype)initWithIncomingMessage:(TSIncomingMessage *)message storageManager:(TSStorageManager *)storageManager
{ {
// Only groupthread sets authorId, thus this crappy code. // authorId isn't set on all legacy messages, so we take
// TODO ALL incoming messages should have an authorId. // extra measures to ensure we obtain a valid value.
NSString *messageAuthorId; NSString *messageAuthorId;
if (message.authorId) { // Group Thread if (message.authorId) { // Group Thread
messageAuthorId = message.authorId; messageAuthorId = message.authorId;

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/24/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSSendReadReceiptsJob.h" #import "OWSSendReadReceiptsJob.h"
#import "OWSMessageSender.h" #import "OWSMessageSender.h"
@ -41,8 +42,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)runWith:(TSIncomingMessage *)message - (void)runWith:(TSIncomingMessage *)message
{ {
// Only groupthread sets authorId, thus this crappy code. // authorId isn't set on all legacy messages, so we take
// TODO Refactor so that ALL incoming messages have an authorId. // extra measures to ensure we obtain a valid value.
NSString *messageAuthorId; NSString *messageAuthorId;
if (message.authorId) { // Group Thread if (message.authorId) { // Group Thread
messageAuthorId = message.authorId; messageAuthorId = message.authorId;

@ -92,8 +92,8 @@ NSString *const TSIncomingMessageWasReadOnThisDeviceNotification = @"TSIncomingM
if ([interaction isKindOfClass:[TSIncomingMessage class]]) { if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *message = (TSIncomingMessage *)interaction; TSIncomingMessage *message = (TSIncomingMessage *)interaction;
// Only groupthread sets authorId, thus this crappy code. // authorId isn't set on all legacy messages, so we take
// TODO ALL incoming messages should have an authorId. // extra measures to ensure we obtain a valid value.
NSString *messageAuthorId; NSString *messageAuthorId;
if (message.authorId) { // Group Thread if (message.authorId) { // Group Thread
messageAuthorId = message.authorId; messageAuthorId = message.authorId;

@ -3,6 +3,7 @@
// //
#import "OWSBatchMessageProcessor.h" #import "OWSBatchMessageProcessor.h"
#import "NSArray+OWS.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
#import "TSMessagesManager.h" #import "TSMessagesManager.h"
@ -19,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosEnvelope;
@interface OWSBatchMessageProcessingJob : TSYapDatabaseObject @interface OWSMessageContentJob : TSYapDatabaseObject
@property (nonatomic, readonly) NSDate *createdAt; @property (nonatomic, readonly) NSDate *createdAt;
@ -32,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - #pragma mark -
@interface OWSBatchMessageProcessingJob () @interface OWSMessageContentJob ()
@property (nonatomic, readonly) NSData *envelopeData; @property (nonatomic, readonly) NSData *envelopeData;
@property (nonatomic, readonly, nullable) NSData *plaintextData; @property (nonatomic, readonly, nullable) NSData *plaintextData;
@ -41,7 +42,12 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - #pragma mark -
@implementation OWSBatchMessageProcessingJob @implementation OWSMessageContentJob
+ (NSString *)collection
{
return @"OWSBatchMessageProcessingJob";
}
- (instancetype)initWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData - (instancetype)initWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData
{ {
@ -68,20 +74,16 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Finder #pragma mark - Finder
NSString *const OWSBatchMessageProcessingJobFinderExtensionName = @"OWSBatchMessageProcessingJobFinderExtensionName"; NSString *const OWSMessageContentJobFinderExtensionName = @"OWSBatchMessageProcessingFinderExtensionName";
NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMessageProcessingJobFinderExtensionGroup"; NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSBatchMessageProcessingFinderExtensionGroup";
@interface OWSBatchMessageProcessingJobFinder : NSObject
- (NSArray<OWSBatchMessageProcessingJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize; @interface OWSMessageContentJobFinder : NSObject
- (void)addJobWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData;
- (void)removeJobWithId:(NSString *)uniqueId;
@end @end
#pragma mark - #pragma mark -
@interface OWSBatchMessageProcessingJobFinder () @interface OWSMessageContentJobFinder ()
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@ -89,7 +91,7 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
#pragma mark - #pragma mark -
@implementation OWSBatchMessageProcessingJobFinder @implementation OWSMessageContentJobFinder
- (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection - (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection
{ {
@ -105,50 +107,41 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
return self; return self;
} }
- (NSArray<OWSBatchMessageProcessingJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize - (NSArray<OWSMessageContentJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize
{ {
NSMutableArray<OWSBatchMessageProcessingJob *> *jobs = [NSMutableArray new]; NSMutableArray<OWSMessageContentJob *> *jobs = [NSMutableArray new];
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
YapDatabaseViewTransaction *viewTransaction = [transaction ext:OWSBatchMessageProcessingJobFinderExtensionName]; YapDatabaseViewTransaction *viewTransaction = [transaction ext:OWSMessageContentJobFinderExtensionName];
OWSAssert(viewTransaction != nil); OWSAssert(viewTransaction != nil);
NSMutableArray<NSString *> *jobIds = [NSMutableArray new]; [viewTransaction enumerateKeysAndObjectsInGroup:OWSMessageContentJobFinderExtensionGroup
[viewTransaction enumerateKeysInGroup:OWSBatchMessageProcessingJobFinderExtensionGroup usingBlock:^(NSString *_Nonnull collection,
usingBlock:^(NSString *_Nonnull collection, NSString *_Nonnull key,
NSString *_Nonnull key, id _Nonnull object,
NSUInteger index, NSUInteger index,
BOOL *_Nonnull stop) { BOOL *_Nonnull stop) {
[jobIds addObject:key]; OWSMessageContentJob *job = object;
if (jobIds.count >= maxBatchSize) { [jobs addObject:job];
*stop = YES; if (jobs.count >= maxBatchSize) {
} *stop = YES;
}]; }
}];
for (NSString *jobId in jobIds) {
OWSBatchMessageProcessingJob *_Nullable job =
[OWSBatchMessageProcessingJob fetchObjectWithUniqueID:jobId transaction:transaction];
if (job) {
[jobs addObject:job];
} else {
OWSFail(@"Could not load job: %@", jobId);
}
}
}]; }];
return jobs; return [jobs copy];
} }
- (void)addJobWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData - (void)addJobWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData
{ {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[[[OWSBatchMessageProcessingJob alloc] initWithEnvelopeData:envelopeData plaintextData:plaintextData] [[[OWSMessageContentJob alloc] initWithEnvelopeData:envelopeData plaintextData:plaintextData]
saveWithTransaction:transaction]; saveWithTransaction:transaction];
}]; }];
} }
- (void)removeJobWithId:(NSString *)uniqueId - (void)removeJobsWithIds:(NSArray<NSString *> *)uniqueIds
{ {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[transaction removeObjectForKey:uniqueId inCollection:[OWSBatchMessageProcessingJob collection]]; [transaction removeObjectsForKeys:uniqueIds inCollection:[OWSMessageContentJob collection]];
}]; }];
} }
@ -164,17 +157,17 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[OWSBatchMessageProcessingJob class]]) { if (![object1 isKindOfClass:[OWSMessageContentJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", [object1 class], collection1); OWSFail(@"Unexpected object: %@ in collection: %@", [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
OWSBatchMessageProcessingJob *job1 = (OWSBatchMessageProcessingJob *)object1; OWSMessageContentJob *job1 = (OWSMessageContentJob *)object1;
if (![object2 isKindOfClass:[OWSBatchMessageProcessingJob class]]) { if (![object2 isKindOfClass:[OWSMessageContentJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", [object2 class], collection2); OWSFail(@"Unexpected object: %@ in collection: %@", [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
OWSBatchMessageProcessingJob *job2 = (OWSBatchMessageProcessingJob *)object2; OWSMessageContentJob *job2 = (OWSMessageContentJob *)object2;
return [job1.createdAt compare:job2.createdAt]; return [job1.createdAt compare:job2.createdAt];
}]; }];
@ -184,18 +177,18 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
NSString *_Nonnull collection, NSString *_Nonnull collection,
NSString *_Nonnull key, NSString *_Nonnull key,
id _Nonnull object) { id _Nonnull object) {
if (![object isKindOfClass:[OWSBatchMessageProcessingJob class]]) { if (![object isKindOfClass:[OWSMessageContentJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", object, collection); OWSFail(@"Unexpected object: %@ in collection: %@", object, collection);
return nil; return nil;
} }
// Arbitrary string - all in the same group. We're only using the view for sorting. // Arbitrary string - all in the same group. We're only using the view for sorting.
return OWSBatchMessageProcessingJobFinderExtensionGroup; return OWSMessageContentJobFinderExtensionGroup;
}]; }];
YapDatabaseViewOptions *options = [YapDatabaseViewOptions new]; YapDatabaseViewOptions *options = [YapDatabaseViewOptions new];
options.allowedCollections = [[YapWhitelistBlacklist alloc] options.allowedCollections =
initWithWhitelist:[NSSet setWithObject:[OWSBatchMessageProcessingJob collection]]]; [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[OWSMessageContentJob collection]]];
return [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options]; return [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
} }
@ -203,40 +196,40 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
+ (void)syncRegisterDatabaseExtension:(YapDatabase *)database + (void)syncRegisterDatabaseExtension:(YapDatabase *)database
{ {
YapDatabaseView *existingView = [database registeredExtension:OWSBatchMessageProcessingJobFinderExtensionName]; YapDatabaseView *existingView = [database registeredExtension:OWSMessageContentJobFinderExtensionName];
if (existingView) { if (existingView) {
OWSFail(@"%@ was already initialized.", OWSBatchMessageProcessingJobFinderExtensionName); OWSFail(@"%@ was already initialized.", OWSMessageContentJobFinderExtensionName);
// already initialized // already initialized
return; return;
} }
[database registerExtension:[self databaseExtension] withName:OWSBatchMessageProcessingJobFinderExtensionName]; [database registerExtension:[self databaseExtension] withName:OWSMessageContentJobFinderExtensionName];
} }
@end @end
#pragma mark - Queue Processing #pragma mark - Queue Processing
@interface OWSBatchMessageProcessingQueue : NSObject @interface OWSMessageContentQueue : NSObject
@property (nonatomic, readonly) TSMessagesManager *messagesManager; @property (nonatomic, readonly) TSMessagesManager *messagesManager;
@property (nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
@property (nonatomic, readonly) OWSBatchMessageProcessingJobFinder *finder; @property (nonatomic, readonly) OWSMessageContentJobFinder *finder;
@property (nonatomic) BOOL isDrainingQueue; @property (nonatomic) BOOL isDrainingQueue;
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager - (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
storageManager:(TSStorageManager *)storageManager storageManager:(TSStorageManager *)storageManager
finder:(OWSBatchMessageProcessingJobFinder *)finder NS_DESIGNATED_INITIALIZER; finder:(OWSMessageContentJobFinder *)finder NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
@end @end
#pragma mark - #pragma mark -
@implementation OWSBatchMessageProcessingQueue @implementation OWSMessageContentQueue
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager - (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
storageManager:(TSStorageManager *)storageManager storageManager:(TSStorageManager *)storageManager
finder:(OWSBatchMessageProcessingJobFinder *)finder finder:(OWSMessageContentJobFinder *)finder
{ {
OWSSingletonAssert(); OWSSingletonAssert();
@ -299,7 +292,7 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
NSArray<OWSBatchMessageProcessingJob *> *jobs = [self.finder nextJobsForBatchSize:kIncomingMessageBatchSize]; NSArray<OWSMessageContentJob *> *jobs = [self.finder nextJobsForBatchSize:kIncomingMessageBatchSize];
OWSAssert(jobs); OWSAssert(jobs);
if (jobs.count < 1) { if (jobs.count < 1) {
self.isDrainingQueue = NO; self.isDrainingQueue = NO;
@ -310,23 +303,22 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
[self processJobs:jobs [self processJobs:jobs
completion:^{ completion:^{
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
for (OWSBatchMessageProcessingJob *job in jobs) { [self.finder removeJobsWithIds:jobs.uniqueIds];
[self.finder removeJobWithId:job.uniqueId];
}
DDLogVerbose(@"%@ completed %zd jobs. %zd jobs left.", DDLogVerbose(@"%@ completed %zd jobs. %zd jobs left.",
self.tag, self.tag,
jobs.count, jobs.count,
[OWSBatchMessageProcessingJob numberOfKeysInCollection]); [OWSMessageContentJob numberOfKeysInCollection]);
[self drainQueueWorkStep]; [self drainQueueWorkStep];
}); });
}]; }];
} }
- (void)processJobs:(NSArray<OWSBatchMessageProcessingJob *> *)jobs completion:(void (^)())completion - (void)processJobs:(NSArray<OWSMessageContentJob *> *)jobs completion:(void (^)())completion
{ {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (OWSBatchMessageProcessingJob *job in jobs) { for (OWSMessageContentJob *job in jobs) {
[self.messagesManager processEnvelope:job.envelopeProto [self.messagesManager processEnvelope:job.envelopeProto
plaintextData:job.plaintextData plaintextData:job.plaintextData
transaction:transaction]; transaction:transaction];
@ -354,7 +346,7 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
@interface OWSBatchMessageProcessor () @interface OWSBatchMessageProcessor ()
@property (nonatomic, readonly) OWSBatchMessageProcessingQueue *processingQueue; @property (nonatomic, readonly) OWSMessageContentQueue *processingQueue;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@end @end
@ -374,12 +366,10 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
return self; return self;
} }
OWSBatchMessageProcessingJobFinder *finder = OWSMessageContentJobFinder *finder = [[OWSMessageContentJobFinder alloc] initWithDBConnection:dbConnection];
[[OWSBatchMessageProcessingJobFinder alloc] initWithDBConnection:dbConnection]; OWSMessageContentQueue *processingQueue = [[OWSMessageContentQueue alloc] initWithMessagesManager:messagesManager
OWSBatchMessageProcessingQueue *processingQueue = storageManager:storageManager
[[OWSBatchMessageProcessingQueue alloc] initWithMessagesManager:messagesManager finder:finder];
storageManager:storageManager
finder:finder];
_processingQueue = processingQueue; _processingQueue = processingQueue;
@ -412,7 +402,7 @@ NSString *const OWSBatchMessageProcessingJobFinderExtensionGroup = @"OWSBatchMes
+ (void)syncRegisterDatabaseExtension:(YapDatabase *)database + (void)syncRegisterDatabaseExtension:(YapDatabase *)database
{ {
[OWSBatchMessageProcessingJobFinder syncRegisterDatabaseExtension:database]; [OWSMessageContentJobFinder syncRegisterDatabaseExtension:database];
} }
#pragma mark - instance methods #pragma mark - instance methods

@ -23,6 +23,8 @@ extern NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange;
- (NSArray<NSString *> *)blockedPhoneNumbers; - (NSArray<NSString *> *)blockedPhoneNumbers;
- (BOOL)isRecipientIdBlocked:(NSString *)recipientId;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -161,6 +161,11 @@ NSString *const kOWSBlockingManager_SyncedBlockedPhoneNumbersKey = @"kOWSBlockin
} }
} }
- (BOOL)isRecipientIdBlocked:(NSString *)recipientId
{
return [self.blockedPhoneNumbers containsObject:recipientId];
}
// This should be called every time the block list changes. // This should be called every time the block list changes.
- (void)handleUpdate - (void)handleUpdate

@ -3,6 +3,7 @@
// //
#import "OWSMessageReceiver.h" #import "OWSMessageReceiver.h"
#import "NSArray+OWS.h"
#import "OWSBatchMessageProcessor.h" #import "OWSBatchMessageProcessor.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
@ -20,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosEnvelope;
@interface OWSMessageProcessingJob : TSYapDatabaseObject @interface OWSMessageDecryptJob : TSYapDatabaseObject
@property (nonatomic, readonly) NSDate *createdAt; @property (nonatomic, readonly) NSDate *createdAt;
@ -32,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - #pragma mark -
@interface OWSMessageProcessingJob () @interface OWSMessageDecryptJob ()
@property (nonatomic, readonly) NSData *envelopeData; @property (nonatomic, readonly) NSData *envelopeData;
@ -40,7 +41,12 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - #pragma mark -
@implementation OWSMessageProcessingJob @implementation OWSMessageDecryptJob
+ (NSString *)collection
{
return @"OWSMessageProcessingJob";
}
- (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope - (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
{ {
@ -66,20 +72,16 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Finder #pragma mark - Finder
NSString *const OWSMessageProcessingJobFinderExtensionName = @"OWSMessageProcessingJobFinderExtensionName"; NSString *const OWSMessageDecryptJobFinderExtensionName = @"OWSMessageProcessingJobFinderExtensionName";
NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProcessingJobFinderExtensionGroup"; NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessingJobFinderExtensionGroup";
@interface OWSMessageProcessingJobFinder : NSObject @interface OWSMessageDecryptJobFinder : NSObject
- (NSArray<OWSMessageProcessingJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize;
- (void)addJobForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope;
- (void)removeJobWithId:(NSString *)uniqueId;
@end @end
#pragma mark - #pragma mark -
@interface OWSMessageProcessingJobFinder () @interface OWSMessageDecryptJobFinder ()
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@ -87,7 +89,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
#pragma mark - #pragma mark -
@implementation OWSMessageProcessingJobFinder @implementation OWSMessageDecryptJobFinder
- (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection - (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection
{ {
@ -103,49 +105,40 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
return self; return self;
} }
- (NSArray<OWSMessageProcessingJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize - (NSArray<OWSMessageDecryptJob *> *)nextJobsForBatchSize:(NSUInteger)maxBatchSize
{ {
NSMutableArray<OWSMessageProcessingJob *> *jobs = [NSMutableArray new]; NSMutableArray<OWSMessageDecryptJob *> *jobs = [NSMutableArray new];
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
YapDatabaseViewTransaction *viewTransaction = [transaction ext:OWSMessageProcessingJobFinderExtensionName]; YapDatabaseViewTransaction *viewTransaction = [transaction ext:OWSMessageDecryptJobFinderExtensionName];
OWSAssert(viewTransaction != nil); OWSAssert(viewTransaction != nil);
NSMutableArray<NSString *> *jobIds = [NSMutableArray new]; [viewTransaction enumerateKeysAndObjectsInGroup:OWSMessageDecryptJobFinderExtensionGroup
[viewTransaction enumerateKeysInGroup:OWSMessageProcessingJobFinderExtensionGroup usingBlock:^(NSString *_Nonnull collection,
usingBlock:^(NSString *_Nonnull collection, NSString *_Nonnull key,
NSString *_Nonnull key, id _Nonnull object,
NSUInteger index, NSUInteger index,
BOOL *_Nonnull stop) { BOOL *_Nonnull stop) {
[jobIds addObject:key]; OWSMessageDecryptJob *job = object;
if (jobIds.count >= maxBatchSize) { [jobs addObject:job];
*stop = YES; if (jobs.count >= maxBatchSize) {
} *stop = YES;
}]; }
}];
for (NSString *jobId in jobIds) {
OWSMessageProcessingJob *_Nullable job =
[OWSMessageProcessingJob fetchObjectWithUniqueID:jobId transaction:transaction];
if (job) {
[jobs addObject:job];
} else {
OWSFail(@"Could not load job: %@", jobId);
}
}
}]; }];
return jobs; return [jobs copy];
} }
- (void)addJobForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope - (void)addJobForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
{ {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[[[OWSMessageProcessingJob alloc] initWithEnvelope:envelope] saveWithTransaction:transaction]; [[[OWSMessageDecryptJob alloc] initWithEnvelope:envelope] saveWithTransaction:transaction];
}]; }];
} }
- (void)removeJobWithId:(NSString *)uniqueId - (void)removeJobsWithIds:(NSArray<NSString *> *)uniqueIds
{ {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[transaction removeObjectForKey:uniqueId inCollection:[OWSMessageProcessingJob collection]]; [transaction removeObjectsForKeys:uniqueIds inCollection:[OWSMessageDecryptJob collection]];
}]; }];
} }
@ -161,17 +154,17 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[OWSMessageProcessingJob class]]) { if (![object1 isKindOfClass:[OWSMessageDecryptJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", [object1 class], collection1); OWSFail(@"Unexpected object: %@ in collection: %@", [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
OWSMessageProcessingJob *job1 = (OWSMessageProcessingJob *)object1; OWSMessageDecryptJob *job1 = (OWSMessageDecryptJob *)object1;
if (![object2 isKindOfClass:[OWSMessageProcessingJob class]]) { if (![object2 isKindOfClass:[OWSMessageDecryptJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", [object2 class], collection2); OWSFail(@"Unexpected object: %@ in collection: %@", [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
OWSMessageProcessingJob *job2 = (OWSMessageProcessingJob *)object2; OWSMessageDecryptJob *job2 = (OWSMessageDecryptJob *)object2;
return [job1.createdAt compare:job2.createdAt]; return [job1.createdAt compare:job2.createdAt];
}]; }];
@ -181,18 +174,18 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
NSString *_Nonnull collection, NSString *_Nonnull collection,
NSString *_Nonnull key, NSString *_Nonnull key,
id _Nonnull object) { id _Nonnull object) {
if (![object isKindOfClass:[OWSMessageProcessingJob class]]) { if (![object isKindOfClass:[OWSMessageDecryptJob class]]) {
OWSFail(@"Unexpected object: %@ in collection: %@", object, collection); OWSFail(@"Unexpected object: %@ in collection: %@", object, collection);
return nil; return nil;
} }
// Arbitrary string - all in the same group. We're only using the view for sorting. // Arbitrary string - all in the same group. We're only using the view for sorting.
return OWSMessageProcessingJobFinderExtensionGroup; return OWSMessageDecryptJobFinderExtensionGroup;
}]; }];
YapDatabaseViewOptions *options = [YapDatabaseViewOptions new]; YapDatabaseViewOptions *options = [YapDatabaseViewOptions new];
options.allowedCollections = options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[OWSMessageProcessingJob collection]]]; [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[OWSMessageDecryptJob collection]]];
return [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options]; return [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
} }
@ -200,40 +193,40 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
+ (void)syncRegisterDatabaseExtension:(YapDatabase *)database + (void)syncRegisterDatabaseExtension:(YapDatabase *)database
{ {
YapDatabaseView *existingView = [database registeredExtension:OWSMessageProcessingJobFinderExtensionName]; YapDatabaseView *existingView = [database registeredExtension:OWSMessageDecryptJobFinderExtensionName];
if (existingView) { if (existingView) {
OWSFail(@"%@ was already initialized.", OWSMessageProcessingJobFinderExtensionName); OWSFail(@"%@ was already initialized.", OWSMessageDecryptJobFinderExtensionName);
// already initialized // already initialized
return; return;
} }
[database registerExtension:[self databaseExtension] withName:OWSMessageProcessingJobFinderExtensionName]; [database registerExtension:[self databaseExtension] withName:OWSMessageDecryptJobFinderExtensionName];
} }
@end @end
#pragma mark - Queue Processing #pragma mark - Queue Processing
@interface OWSMessageProcessingQueue : NSObject @interface OWSMessageDecryptQueue : NSObject
@property (nonatomic, readonly) TSMessagesManager *messagesManager; @property (nonatomic, readonly) TSMessagesManager *messagesManager;
@property (nonatomic, readonly) OWSBatchMessageProcessor *batchMessageProcessor; @property (nonatomic, readonly) OWSBatchMessageProcessor *batchMessageProcessor;
@property (nonatomic, readonly) OWSMessageProcessingJobFinder *finder; @property (nonatomic, readonly) OWSMessageDecryptJobFinder *finder;
@property (nonatomic) BOOL isDrainingQueue; @property (nonatomic) BOOL isDrainingQueue;
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager - (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor
finder:(OWSMessageProcessingJobFinder *)finder NS_DESIGNATED_INITIALIZER; finder:(OWSMessageDecryptJobFinder *)finder NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
@end @end
#pragma mark - #pragma mark -
@implementation OWSMessageProcessingQueue @implementation OWSMessageDecryptQueue
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager - (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor
finder:(OWSMessageProcessingJobFinder *)finder finder:(OWSMessageDecryptJobFinder *)finder
{ {
OWSSingletonAssert(); OWSSingletonAssert();
@ -294,7 +287,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
NSArray<OWSMessageProcessingJob *> *jobs = [self.finder nextJobsForBatchSize:kIncomingMessageBatchSize]; NSArray<OWSMessageDecryptJob *> *jobs = [self.finder nextJobsForBatchSize:kIncomingMessageBatchSize];
OWSAssert(jobs); OWSAssert(jobs);
if (jobs.count < 1) { if (jobs.count < 1) {
self.isDrainingQueue = NO; self.isDrainingQueue = NO;
@ -305,19 +298,17 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
[self processJobs:jobs [self processJobs:jobs
completion:^{ completion:^{
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
for (OWSMessageProcessingJob *job in jobs) { [self.finder removeJobsWithIds:jobs.uniqueIds];
[self.finder removeJobWithId:job.uniqueId];
}
DDLogVerbose(@"%@ completed %zd jobs. %zd jobs left.", DDLogVerbose(@"%@ completed %zd jobs. %zd jobs left.",
self.tag, self.tag,
jobs.count, jobs.count,
[OWSMessageProcessingJob numberOfKeysInCollection]); [OWSMessageDecryptJob numberOfKeysInCollection]);
[self drainQueueWorkStep]; [self drainQueueWorkStep];
}); });
}]; }];
} }
- (void)processJobs:(NSArray<OWSMessageProcessingJob *> *)jobs completion:(void (^)())completion - (void)processJobs:(NSArray<OWSMessageDecryptJob *> *)jobs completion:(void (^)())completion
{ {
[self processJobs:jobs [self processJobs:jobs
unprocessedJobs:[jobs mutableCopy] unprocessedJobs:[jobs mutableCopy]
@ -325,8 +316,8 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
completion:completion]; completion:completion];
} }
- (void)processJobs:(NSArray<OWSMessageProcessingJob *> *)jobs - (void)processJobs:(NSArray<OWSMessageDecryptJob *> *)jobs
unprocessedJobs:(NSMutableArray<OWSMessageProcessingJob *> *)unprocessedJobs unprocessedJobs:(NSMutableArray<OWSMessageDecryptJob *> *)unprocessedJobs
plaintextDataMap:(NSMutableDictionary<NSString *, NSData *> *)plaintextDataMap plaintextDataMap:(NSMutableDictionary<NSString *, NSData *> *)plaintextDataMap
completion:(void (^)())completion completion:(void (^)())completion
{ {
@ -334,7 +325,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
OWSAssert(unprocessedJobs.count <= jobs.count); OWSAssert(unprocessedJobs.count <= jobs.count);
if (unprocessedJobs.count < 1) { if (unprocessedJobs.count < 1) {
for (OWSMessageProcessingJob *job in jobs) { for (OWSMessageDecryptJob *job in jobs) {
NSData *_Nullable plaintextData = plaintextDataMap[job.uniqueId]; NSData *_Nullable plaintextData = plaintextDataMap[job.uniqueId];
[self.batchMessageProcessor enqueueEnvelopeData:job.envelopeData plaintextData:plaintextData]; [self.batchMessageProcessor enqueueEnvelopeData:job.envelopeData plaintextData:plaintextData];
} }
@ -344,7 +335,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
OWSAssert(unprocessedJobs.count > 0); OWSAssert(unprocessedJobs.count > 0);
OWSMessageProcessingJob *job = unprocessedJobs.firstObject; OWSMessageDecryptJob *job = unprocessedJobs.firstObject;
[unprocessedJobs removeObjectAtIndex:0]; [unprocessedJobs removeObjectAtIndex:0];
[self.messagesManager decryptEnvelope:job.envelopeProto [self.messagesManager decryptEnvelope:job.envelopeProto
successBlock:^(NSData *_Nullable plaintextData) { successBlock:^(NSData *_Nullable plaintextData) {
@ -383,7 +374,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
@interface OWSMessageReceiver () @interface OWSMessageReceiver ()
@property (nonatomic, readonly) OWSMessageProcessingQueue *processingQueue; @property (nonatomic, readonly) OWSMessageDecryptQueue *processingQueue;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@end @end
@ -403,11 +394,11 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
return self; return self;
} }
OWSMessageProcessingJobFinder *finder = [[OWSMessageProcessingJobFinder alloc] initWithDBConnection:dbConnection]; OWSMessageDecryptJobFinder *finder = [[OWSMessageDecryptJobFinder alloc] initWithDBConnection:dbConnection];
OWSMessageProcessingQueue *processingQueue = OWSMessageDecryptQueue *processingQueue =
[[OWSMessageProcessingQueue alloc] initWithMessagesManager:messagesManager [[OWSMessageDecryptQueue alloc] initWithMessagesManager:messagesManager
batchMessageProcessor:batchMessageProcessor batchMessageProcessor:batchMessageProcessor
finder:finder]; finder:finder];
_processingQueue = processingQueue; _processingQueue = processingQueue;
@ -442,7 +433,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
+ (void)syncRegisterDatabaseExtension:(YapDatabase *)database + (void)syncRegisterDatabaseExtension:(YapDatabase *)database
{ {
[OWSMessageProcessingJobFinder syncRegisterDatabaseExtension:database]; [OWSMessageDecryptJobFinder syncRegisterDatabaseExtension:database];
} }
#pragma mark - instance methods #pragma mark - instance methods

@ -65,6 +65,7 @@ NS_SWIFT_NAME(MessageSender)
* Send and resend text messages or resend messages with existing attachments. * Send and resend text messages or resend messages with existing attachments.
* If you haven't yet created the attachment, see the `sendAttachmentData:` variants. * If you haven't yet created the attachment, see the `sendAttachmentData:` variants.
*/ */
// TODO: make transaction nonnull and remove `sendMessage:success:failure`
- (void)sendMessage:(TSOutgoingMessage *)message - (void)sendMessage:(TSOutgoingMessage *)message
success:(void (^)())successHandler success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler; failure:(void (^)(NSError *error))failureHandler;

@ -636,8 +636,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// you might, for example, have a pending outgoing message when // you might, for example, have a pending outgoing message when
// you block them. // you block them.
OWSAssert(recipientContactId.length > 0); OWSAssert(recipientContactId.length > 0);
NSArray<NSString *> *blockedPhoneNumbers = _blockingManager.blockedPhoneNumbers; if ([_blockingManager isRecipientIdBlocked:recipientContactId]) {
if ([blockedPhoneNumbers containsObject:recipientContactId]) {
DDLogInfo(@"%@ skipping 1:1 send to blocked contact: %@", self.tag, recipientContactId); DDLogInfo(@"%@ skipping 1:1 send to blocked contact: %@", self.tag, recipientContactId);
NSError *error = OWSErrorMakeMessageSendFailedToBlockListError(); NSError *error = OWSErrorMakeMessageSendFailedToBlockListError();
// No need to retry - the user will continue to be blocked. // No need to retry - the user will continue to be blocked.

@ -275,7 +275,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
{ {
OWSAssert(envelope); OWSAssert(envelope);
return [_blockingManager.blockedPhoneNumbers containsObject:envelope.source]; return [_blockingManager isRecipientIdBlocked:envelope.source];
} }
#pragma mark - Decryption #pragma mark - Decryption
@ -375,9 +375,6 @@ const NSUInteger kIncomingMessageBatchSize = 10;
[self decryptEnvelope:envelope [self decryptEnvelope:envelope
messageTypeName:@"Secure Message" messageTypeName:@"Secure Message"
missingPayloadBlock:^{
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
}
cipherMessageBlock:^(NSData *encryptedData) { cipherMessageBlock:^(NSData *encryptedData) {
return [[WhisperMessage alloc] initWithData:encryptedData]; return [[WhisperMessage alloc] initWithData:encryptedData];
} }
@ -398,9 +395,6 @@ const NSUInteger kIncomingMessageBatchSize = 10;
[self decryptEnvelope:envelope [self decryptEnvelope:envelope
messageTypeName:@"PreKey Bundle" messageTypeName:@"PreKey Bundle"
missingPayloadBlock:^{
OWSProdFail([OWSAnalyticsEvents messageManagerErrorPrekeyBundleEnvelopeHasNoContent]);
}
cipherMessageBlock:^(NSData *encryptedData) { cipherMessageBlock:^(NSData *encryptedData) {
return [[PreKeyWhisperMessage alloc] initWithData:encryptedData]; return [[PreKeyWhisperMessage alloc] initWithData:encryptedData];
} }
@ -410,26 +404,24 @@ const NSUInteger kIncomingMessageBatchSize = 10;
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope - (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
messageTypeName:(NSString *)messageTypeName messageTypeName:(NSString *)messageTypeName
missingPayloadBlock:(void (^_Nonnull)())missingPayloadBlock
cipherMessageBlock:(id<CipherMessage> (^_Nonnull)(NSData *))cipherMessageBlock cipherMessageBlock:(id<CipherMessage> (^_Nonnull)(NSData *))cipherMessageBlock
successBlock:(DecryptSuccessBlock)successBlock successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{ {
OWSAssert(envelope); OWSAssert(envelope);
OWSAssert(messageTypeName.length > 0); OWSAssert(messageTypeName.length > 0);
OWSAssert(missingPayloadBlock);
OWSAssert(cipherMessageBlock); OWSAssert(cipherMessageBlock);
OWSAssert(successBlock); OWSAssert(successBlock);
OWSAssert(failureBlock); OWSAssert(failureBlock);
TSStorageManager *storageManager = [TSStorageManager sharedManager]; TSStorageManager *storageManager = self.storageManager;
NSString *recipientId = envelope.source; NSString *recipientId = envelope.source;
int deviceId = envelope.sourceDevice; int deviceId = envelope.sourceDevice;
// DEPRECATED - Remove after all clients have been upgraded. // DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData = envelope.hasContent ? envelope.content : envelope.legacyMessage; NSData *encryptedData = envelope.hasContent ? envelope.content : envelope.legacyMessage;
if (!encryptedData) { if (!encryptedData) {
missingPayloadBlock(); OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
failureBlock(nil); failureBlock(nil);
return; return;
} }
@ -468,7 +460,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
OWSAssert(transaction); OWSAssert(transaction);
OWSAssert([TSAccountManager isRegistered]); OWSAssert([TSAccountManager isRegistered]);
DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]); DDLogInfo(@"%@ handling decrypted envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
OWSAssert(envelope.source.length > 0); OWSAssert(envelope.source.length > 0);
OWSAssert(![self isEnvelopeBlocked:envelope]); OWSAssert(![self isEnvelopeBlocked:envelope]);
@ -510,6 +502,8 @@ const NSUInteger kIncomingMessageBatchSize = 10;
if ([interaction isKindOfClass:[TSOutgoingMessage class]]) { if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)interaction; TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)interaction;
[outgoingMessage updateWithWasDeliveredWithTransaction:transaction]; [outgoingMessage updateWithWasDeliveredWithTransaction:transaction];
} else {
OWSFail(@"%@ Unexpected message with timestamp: %llu", self.tag, envelope.timestamp);
} }
} }
@ -653,7 +647,9 @@ const NSUInteger kIncomingMessageBatchSize = 10;
[self.profileManager setProfileKeyData:profileKey forRecipientId:recipientId]; [self.profileManager setProfileKeyData:profileKey forRecipientId:recipientId];
} }
// TODO: Should we do this synchronously? // By dispatching async, we introduce the possibility that these messages might be lost
// if the app exits before this block is executed. This is fine, since the call by
// definition will end if the app exits.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (callMessage.hasOffer) { if (callMessage.hasOffer) {
[self.callMessageHandler receivedOffer:callMessage.offer fromCallerId:envelope.source]; [self.callMessageHandler receivedOffer:callMessage.offer fromCallerId:envelope.source];
@ -801,7 +797,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
TSGroupThread *groupThread = TSGroupThread *groupThread =
[TSGroupThread getOrCreateThreadWithGroupIdData:syncMessage.sent.message.group.id [TSGroupThread getOrCreateThreadWithGroupIdData:syncMessage.sent.message.group.id
transaction:transaction]; transaction:transaction];
[groupThread updateAvatarWithAttachmentStream:attachmentStream transaction:transaction]; [groupThread updateAvatarWithAttachmentStream:attachmentStream];
} }
transaction:transaction]; transaction:transaction];
} else { } else {
@ -844,6 +840,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
DDLogWarn(@"%@ ignoring unsupported sync request message", self.tag); DDLogWarn(@"%@ ignoring unsupported sync request message", self.tag);
} }
} else if (syncMessage.hasBlocked) { } else if (syncMessage.hasBlocked) {
// TODO: Do this synchronously.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
NSArray<NSString *> *blockedPhoneNumbers = [syncMessage.blocked.numbers copy]; NSArray<NSString *> *blockedPhoneNumbers = [syncMessage.blocked.numbers copy];
[_blockingManager setBlockedPhoneNumbers:blockedPhoneNumbers sendSyncMessage:NO]; [_blockingManager setBlockedPhoneNumbers:blockedPhoneNumbers sendSyncMessage:NO];
@ -857,6 +854,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
[readReceiptsProcessor processWithTransaction:transaction]; [readReceiptsProcessor processWithTransaction:transaction];
} else if (syncMessage.hasVerified) { } else if (syncMessage.hasVerified) {
DDLogInfo(@"%@ Received verification state for %@", self.tag, syncMessage.verified.destination); DDLogInfo(@"%@ Received verification state for %@", self.tag, syncMessage.verified.destination);
// TODO: Do this synchronously.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self.identityManager processIncomingSyncMessage:syncMessage.verified]; [self.identityManager processIncomingSyncMessage:syncMessage.verified];
}); });
@ -875,14 +873,12 @@ const NSUInteger kIncomingMessageBatchSize = 10;
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction]; TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction];
if (thread) { // TODO thread should always be nonnull. [[[TSInfoMessage alloc] initWithTimestamp:envelope.timestamp
[[[TSInfoMessage alloc] initWithTimestamp:envelope.timestamp inThread:thread
inThread:thread messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction];
messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction];
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{ dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager] deleteAllSessionsForContact:envelope.source]; [self.storageManager deleteAllSessionsForContact:envelope.source];
}); });
} }
@ -1186,6 +1182,7 @@ const NSUInteger kIncomingMessageBatchSize = 10;
} }
if (thread && incomingMessage) { if (thread && incomingMessage) {
// TODO: Do this synchronously.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
// In case we already have a read receipt for this new message (happens sometimes). // In case we already have a read receipt for this new message (happens sometimes).
OWSReadReceiptsProcessor *readReceiptsProcessor = OWSReadReceiptsProcessor *readReceiptsProcessor =

@ -0,0 +1,13 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface NSArray (OWS)
- (NSArray<NSString *> *)uniqueIds;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,25 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "NSArray+OWS.h"
#import "TSYapDatabaseObject.h"
NS_ASSUME_NONNULL_BEGIN
@implementation NSArray (OWS)
- (NSArray<NSString *> *)uniqueIds
{
NSMutableArray<NSString *> *result = [NSMutableArray new];
for (id object in self) {
OWSAssert([object isKindOfClass:[TSYapDatabaseObject class]]);
TSYapDatabaseObject *dbObject = object;
[result addObject:dbObject.uniqueId];
}
return result;
}
@end
NS_ASSUME_NONNULL_END

@ -126,8 +126,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)messageManagerErrorOversizeMessage; + (NSString *)messageManagerErrorOversizeMessage;
+ (NSString *)messageManagerErrorPrekeyBundleEnvelopeHasNoContent;
+ (NSString *)messageManagerErrorSyncMessageFromUnknownSource; + (NSString *)messageManagerErrorSyncMessageFromUnknownSource;
+ (NSString *)messageManagerErrorUntrustedIdentityKeyException; + (NSString *)messageManagerErrorUntrustedIdentityKeyException;

@ -297,11 +297,6 @@ NS_ASSUME_NONNULL_BEGIN
return @"message_manager_error_oversize_message"; return @"message_manager_error_oversize_message";
} }
+ (NSString *)messageManagerErrorPrekeyBundleEnvelopeHasNoContent
{
return @"message_manager_error_prekey_bundle_envelope_has_no_content";
}
+ (NSString *)messageManagerErrorSyncMessageFromUnknownSource + (NSString *)messageManagerErrorSyncMessageFromUnknownSource
{ {
return @"message_manager_error_sync_message_from_unknown_source"; return @"message_manager_error_sync_message_from_unknown_source";

Loading…
Cancel
Save