From bd416176ae1c3758b7734b7e5ac2e55c2cf90ad2 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 22 Sep 2017 00:31:13 -0400 Subject: [PATCH] Add stress group to debug UI. // FREEBIE --- Signal.xcodeproj/project.pbxproj | 10 +- .../ConversationViewController.m | 14 +- .../src/ViewControllers/DebugUI/DebugUIMisc.m | 29 ---- .../ViewControllers/DebugUI/DebugUIStress.h | 15 ++ .../ViewControllers/DebugUI/DebugUIStress.m | 136 ++++++++++++++++++ .../DebugUI/DebugUITableViewController.m | 3 + .../src/ViewControllers/HomeViewController.m | 7 + .../Interactions/OWSDynamicOutgoingMessage.h | 20 +++ .../Interactions/OWSDynamicOutgoingMessage.m | 58 ++++++++ 9 files changed, 256 insertions(+), 36 deletions(-) create mode 100644 Signal/src/ViewControllers/DebugUI/DebugUIStress.h create mode 100644 Signal/src/ViewControllers/DebugUI/DebugUIStress.m create mode 100644 SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.h create mode 100644 SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index b8abedc39..09d4b7295 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ 34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; }; 34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */; }; 34B3F8A21E8EA6040035BE1A /* ViewControllerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */; }; + 34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2A1F74C12700D7438D /* DebugUIStress.m */; }; 34C04D801F6195E6004308B3 /* OWSFlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C04D7F1F6195E6004308B3 /* OWSFlatButton.swift */; }; 34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */; }; 34C42D611F4734CA0072EC04 /* OWSContactOffersCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D601F4734CA0072EC04 /* OWSContactOffersCell.m */; }; @@ -514,6 +515,8 @@ 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = ""; }; 34B3F8A01E8EA6040035BE1A /* ViewControllerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewControllerUtils.h; sourceTree = ""; }; 34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllerUtils.m; sourceTree = ""; }; + 34BECE291F74C12700D7438D /* DebugUIStress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIStress.h; sourceTree = ""; }; + 34BECE2A1F74C12700D7438D /* DebugUIStress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIStress.m; sourceTree = ""; }; 34C04D7F1F6195E6004308B3 /* OWSFlatButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSFlatButton.swift; sourceTree = ""; }; 34C42D591F45F7A80072EC04 /* OWSNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSNavigationController.h; sourceTree = ""; }; 34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSNavigationController.m; sourceTree = ""; }; @@ -1121,6 +1124,7 @@ 34D8C0221ED3673300188D7C /* DebugUI */ = { isa = PBXGroup; children = ( + 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */, 34D8C0291ED3685800188D7C /* DebugUIContacts.h */, 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */, 34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */, @@ -1131,12 +1135,13 @@ 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */, 34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */, 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */, + 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */, 452037CF1EE84975004E4CDF /* DebugUISessionState.h */, 452037D01EE84975004E4CDF /* DebugUISessionState.m */, + 34BECE291F74C12700D7438D /* DebugUIStress.h */, + 34BECE2A1F74C12700D7438D /* DebugUIStress.m */, 34D8C0251ED3673300188D7C /* DebugUITableViewController.h */, 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */, - 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */, - 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */, ); path = DebugUI; sourceTree = ""; @@ -2340,6 +2345,7 @@ 341207271EE19F6A00463194 /* OWSSystemMessageCell.m in Sources */, 341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */, 34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */, + 34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */, 45F2B1941D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m in Sources */, 34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */, B68EF9BA1C0B1EBD009C3DCD /* FLAnimatedImage.m in Sources */, diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index e95f64b6b..5d830e460 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -2,18 +2,18 @@ // Copyright (c) 2017 Open Whisper Systems. All rights reserved. // +#import "ConversationViewController.h" #import "AppDelegate.h" #import "AttachmentSharing.h" #import "BlockListUIUtils.h" #import "BlockListViewController.h" #import "ContactsViewHelper.h" -#import "ConversationViewController.h" #import "DebugUITableViewController.h" #import "Environment.h" #import "FingerprintViewController.h" #import "FullImageViewController.h" -#import "NewGroupViewController.h" #import "NSDate+millisecondTimeStamp.h" +#import "NewGroupViewController.h" #import "OWSAudioAttachmentPlayer.h" #import "OWSCall.h" #import "OWSContactOffersCell.h" @@ -34,7 +34,6 @@ #import "OWSUnreadIndicatorCell.h" #import "Signal-Swift.h" #import "SignalKeyingStorage.h" -#import "ThreadUtil.h" #import "TSAttachmentPointer.h" #import "TSCall.h" #import "TSContactThread.h" @@ -47,14 +46,15 @@ #import "TSInfoMessage.h" #import "TSInvalidIdentityKeyErrorMessage.h" #import "TSUnreadIndicatorInteraction.h" +#import "ThreadUtil.h" #import "UIFont+OWS.h" #import "UIUtil.h" #import "UIViewController+CameraPermissions.h" #import "UIViewController+OWS.h" #import "ViewControllerUtils.h" +#import #import #import -#import #import #import #import @@ -80,11 +80,11 @@ #import #import #import -#import #import #import #import #import +#import #import @import Photos; @@ -648,6 +648,10 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { [self createScrollDownButton]; [self createHeaderViews]; [self addNotificationListeners]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [DebugUITableViewController presentDebugUIForThread:self.thread fromViewController:self]; + }); } - (void)registerCustomMessageNibs diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m index 30284e0b0..ec66c4a93 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m @@ -61,13 +61,6 @@ NS_ASSUME_NONNULL_BEGIN actionBlock:^{ [DebugUIMisc clearHasDismissedOffers]; }]]; - if ([thread isKindOfClass:[TSGroupThread class]]) { - TSGroupThread *groupThread = (TSGroupThread *)thread; - [items addObject:[OWSTableItem itemWithTitle:@"Hallucinate twin group" - actionBlock:^{ - [DebugUIMisc hallucinateTwinGroup:groupThread]; - }]]; - } return [OWSTableSection sectionWithTitle:self.name items:items]; } @@ -122,28 +115,6 @@ NS_ASSUME_NONNULL_BEGIN }]; } -// Creates a new group (by cloning the current group) without informing the, -// other members. This can be used to test "group info requests", etc. -+ (void)hallucinateTwinGroup:(TSGroupThread *)groupThread -{ - __block TSGroupThread *thread; - [[TSStorageManager sharedManager].dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - TSGroupModel *groupModel = - [[TSGroupModel alloc] initWithTitle:[groupThread.groupModel.groupName stringByAppendingString:@" Copy"] - memberIds:[groupThread.groupModel.groupMemberIds mutableCopy] - image:groupThread.groupModel.groupImage - groupId:[SecurityUtils generateRandomBytes:16]]; - thread = [TSGroupThread getOrCreateThreadWithGroupModel:groupModel transaction:transaction]; - }]; - OWSAssert(thread); - - dispatch_async(dispatch_get_main_queue(), ^{ - [Environment presentConversationForThread:thread]; - - }); -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIStress.h b/Signal/src/ViewControllers/DebugUI/DebugUIStress.h new file mode 100644 index 000000000..6a9aa1dbe --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUIStress.h @@ -0,0 +1,15 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "DebugUIPage.h" + +NS_ASSUME_NONNULL_BEGIN + +@class TSThread; + +@interface DebugUIStress : DebugUIPage + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIStress.m b/Signal/src/ViewControllers/DebugUI/DebugUIStress.m new file mode 100644 index 000000000..e61563532 --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUIStress.m @@ -0,0 +1,136 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "DebugUIStress.h" +#import "Environment.h" +#import "OWSMessageSender.h" +#import "OWSTableViewController.h" +#import "ThreadUtil.h" +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation DebugUIStress + +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag +{ + return self.class.tag; +} + +#pragma mark - Factory Methods + +- (NSString *)name +{ + return @"Stress"; +} + +- (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread +{ + OWSAssert(thread); + + NSMutableArray *items = [NSMutableArray new]; + [items addObject:[OWSTableItem itemWithTitle:@"Send empty message" + actionBlock:^{ + [DebugUIStress sendStressMessage:thread block:^(SignalRecipient *recipient) { + return [NSData new]; + }]; + }]]; + [items addObject:[OWSTableItem itemWithTitle:@"Send no payload message" + actionBlock:^{ + [DebugUIStress sendStressMessage:thread block:^(SignalRecipient *recipient) { + OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new]; + return [[contentBuilder build] data]; + }]; + }]]; + [items addObject:[OWSTableItem itemWithTitle:@"Send empty null message" + actionBlock:^{ + [DebugUIStress sendStressMessage:thread block:^(SignalRecipient *recipient) { + OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new]; + OWSSignalServiceProtosNullMessageBuilder *nullMessageBuilder = [OWSSignalServiceProtosNullMessageBuilder new]; + contentBuilder.nullMessage = [nullMessageBuilder build]; + return [[contentBuilder build] data]; + }]; + }]]; + [items addObject:[OWSTableItem itemWithTitle:@"Send random null message" + actionBlock:^{ + [DebugUIStress sendStressMessage:thread block:^(SignalRecipient *recipient) { + OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new]; + OWSSignalServiceProtosNullMessageBuilder *nullMessageBuilder = [OWSSignalServiceProtosNullMessageBuilder new]; + NSUInteger contentLength = arc4random_uniform(32); + nullMessageBuilder.padding = [Cryptography generateRandomBytes:contentLength]; + contentBuilder.nullMessage = [nullMessageBuilder build]; + // contentBuilder.dataMessage = [self buildDataMessage:recipient.recipientId]; + return [[contentBuilder build] data]; + }]; + }]]; + + if ([thread isKindOfClass:[TSGroupThread class]]) { + TSGroupThread *groupThread = (TSGroupThread *)thread; + [items addObject:[OWSTableItem itemWithTitle:@"Hallucinate twin group" + actionBlock:^{ + [DebugUIStress hallucinateTwinGroup:groupThread]; + }]]; + } + return [OWSTableSection sectionWithTitle:self.name items:items]; +} + ++ (void)sendStressMessage:(TSOutgoingMessage *)message +{ + OWSAssert(message); + + OWSMessageSender *messageSender = [Environment getCurrent].messageSender; + [messageSender sendMessage:message + success:^{ + DDLogInfo(@"%@ Successfully sent message.", self.tag); + } + failure:^(NSError *error) { + DDLogWarn(@"%@ Failed to deliver message with error: %@", self.tag, error); + }]; +} + ++ (void)sendStressMessage:(TSThread *)thread + block:(DynamicOutgoingMessageBlock)block +{ + OWSAssert(thread); + OWSAssert(block); + + OWSDynamicOutgoingMessage *message = [[OWSDynamicOutgoingMessage alloc] initWithBlock:block inThread:thread]; + + [self sendStressMessage:message]; +} + +// Creates a new group (by cloning the current group) without informing the, +// other members. This can be used to test "group info requests", etc. ++ (void)hallucinateTwinGroup:(TSGroupThread *)groupThread +{ + __block TSGroupThread *thread; + [[TSStorageManager sharedManager].dbReadWriteConnection + readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + TSGroupModel *groupModel = + [[TSGroupModel alloc] initWithTitle:[groupThread.groupModel.groupName stringByAppendingString:@" Copy"] + memberIds:[groupThread.groupModel.groupMemberIds mutableCopy] + image:groupThread.groupModel.groupImage + groupId:[SecurityUtils generateRandomBytes:16]]; + thread = [TSGroupThread getOrCreateThreadWithGroupModel:groupModel transaction:transaction]; + }]; + OWSAssert(thread); + + [Environment presentConversationForThread:thread]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index f1b9e6dad..e5e8b27e5 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -8,6 +8,7 @@ #import "DebugUIMessages.h" #import "DebugUIMisc.h" #import "DebugUISessionState.h" +#import "DebugUIStress.h" #import "Signal-Swift.h" #import #import @@ -96,6 +97,8 @@ NS_ASSUME_NONNULL_BEGIN addObject:[self itemForSubsection:[DebugUICalling new] viewController:viewController thread:thread]]; } [subsectionItems addObject:[self itemForSubsection:[DebugUIProfile new] viewController:viewController thread:thread]]; + [subsectionItems + addObject:[self itemForSubsection:[DebugUIStress new] viewController:viewController thread:thread]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]]; [contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]]; diff --git a/Signal/src/ViewControllers/HomeViewController.m b/Signal/src/ViewControllers/HomeViewController.m index a79e7351e..85efe3786 100644 --- a/Signal/src/ViewControllers/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeViewController.m @@ -273,6 +273,13 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; } [self updateBarButtonItems]; + + dispatch_async(dispatch_get_main_queue(), ^{ + TSThread *thread = [self threadForIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + if (thread) { + [self presentThread:thread keyboardOnViewAppearing:NO callOnViewAppearing:NO]; + } + }); } - (void)updateBarButtonItems diff --git a/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.h new file mode 100644 index 000000000..b8358a5ee --- /dev/null +++ b/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "TSOutgoingMessage.h" + +NS_ASSUME_NONNULL_BEGIN + +@class OWSSignalServiceProtosDataMessageBuilder; +@class SignalRecipient; + +typedef NSData *_Nonnull (^DynamicOutgoingMessageBlock)(SignalRecipient *); + +@interface OWSDynamicOutgoingMessage : TSOutgoingMessage + +- (instancetype)initWithBlock:(DynamicOutgoingMessageBlock)block inThread:(nullable TSThread *)thread; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.m new file mode 100644 index 000000000..295e7abad --- /dev/null +++ b/SignalServiceKit/src/Messages/Interactions/OWSDynamicOutgoingMessage.m @@ -0,0 +1,58 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "OWSDynamicOutgoingMessage.h" +#import "NSDate+millisecondTimeStamp.h" +#import "OWSSignalServiceProtos.pb.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OWSDynamicOutgoingMessage () + +@property (nonatomic, readonly) DynamicOutgoingMessageBlock block; + +@end + +#pragma mark - + +@implementation OWSDynamicOutgoingMessage + +- (instancetype)initWithBlock:(DynamicOutgoingMessageBlock)block inThread:(nullable TSThread *)thread +{ + self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; + + if (self) { + _block = block; + } + + return self; +} + +- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + // override superclass with no-op. + // + // There's no need to save this message, since it's not displayed to the user. +} + +//- (OWSSignalServiceProtosDataMessageBuilder *)dataMessageBuilder +//{ +// OWSSignalServiceProtosDataMessageBuilder *builder = [super dataMessageBuilder]; +// [builder setFlags:OWSSignalServiceProtosDataMessageFlagsEndSession]; +// +// return builder; +//} + +- (NSData *)buildPlainTextData:(SignalRecipient *)recipient +{ + NSData *plainTextData = self.block(recipient); + OWSAssert(plainTextData); + return plainTextData; + // OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new]; + // contentBuilder.dataMessage = [self buildDataMessage:recipient.recipientId]; + // return [[contentBuilder build] data]; +} +@end + +NS_ASSUME_NONNULL_END