Respond to CR.
// FREEBIE
This commit is contained in:
parent
071dbd4414
commit
efcd42012c
@ -9,6 +9,7 @@
|
||||
#import "OWSProfileManager.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import <SignalServiceKit/ECKeyPair+OWSPrivateKey.h>
|
||||
#import <SignalServiceKit/OWSDevice.h>
|
||||
#import <SignalServiceKit/OWSDeviceProvisioner.h>
|
||||
#import <SignalServiceKit/OWSIdentityManager.h>
|
||||
#import <SignalServiceKit/OWSReadReceiptManager.h>
|
||||
@ -18,9 +19,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSLinkDeviceViewController ()
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIView *qrScanningView;
|
||||
@property (strong, nonatomic) IBOutlet UILabel *scanningInstructionsLabel;
|
||||
@property (strong, nonatomic) OWSQRCodeScanningViewController *qrScanningController;
|
||||
@property (nonatomic) YapDatabaseConnection *dbConnection;
|
||||
@property (nonatomic) IBOutlet UIView *qrScanningView;
|
||||
@property (nonatomic) IBOutlet UILabel *scanningInstructionsLabel;
|
||||
@property (nonatomic) OWSQRCodeScanningViewController *qrScanningController;
|
||||
@property (nonatomic, readonly) OWSReadReceiptManager *readReceiptManager;
|
||||
|
||||
@end
|
||||
@ -31,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.dbConnection = [[TSStorageManager sharedManager] newDatabaseConnection];
|
||||
|
||||
// HACK to get full width preview layer
|
||||
CGRect oldFrame = self.qrScanningView.frame;
|
||||
self.qrScanningView.frame = CGRectMake(
|
||||
@ -142,6 +146,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (void)provisionWithParser:(OWSDeviceProvisioningURLParser *)parser
|
||||
{
|
||||
// Optimistically set this flag.
|
||||
[OWSDevice setMayHaveLinkedDevices:YES dbConnection:self.dbConnection];
|
||||
|
||||
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
|
||||
OWSAssert(identityKeyPair);
|
||||
NSData *myPublicKey = identityKeyPair.publicKey;
|
||||
|
||||
@ -20,10 +20,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSLinkedDevicesTableViewController ()
|
||||
|
||||
@property YapDatabaseConnection *dbConnection;
|
||||
@property YapDatabaseViewMappings *deviceMappings;
|
||||
@property NSTimer *pollingRefreshTimer;
|
||||
@property BOOL isExpectingMoreDevices;
|
||||
@property (nonatomic) YapDatabaseConnection *dbConnection;
|
||||
@property (nonatomic) YapDatabaseViewMappings *deviceMappings;
|
||||
@property (nonatomic) NSTimer *pollingRefreshTimer;
|
||||
@property (nonatomic) BOOL isExpectingMoreDevices;
|
||||
|
||||
@end
|
||||
|
||||
@ -131,6 +131,14 @@ int const OWSLinkedDevicesTableViewControllerSectionAddDevice = 1;
|
||||
__weak typeof(self) wself = self;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[[OWSDevicesService new] getDevicesWithSuccess:^(NSArray<OWSDevice *> *devices) {
|
||||
// If we have more than one device; we may have a linked device.
|
||||
if (devices.count > 1) {
|
||||
// Setting this flag here shouldn't be necessary, but we do so
|
||||
// because the "cost" is low and it will improve robustness.
|
||||
[OWSDevice setMayHaveLinkedDevices:YES
|
||||
dbConnection:[[TSStorageManager sharedManager] newDatabaseConnection]];
|
||||
}
|
||||
|
||||
if (devices.count > [OWSDevice numberOfKeysInCollection]) {
|
||||
// Got our new device, we can stop refreshing.
|
||||
wself.isExpectingMoreDevices = NO;
|
||||
@ -243,7 +251,6 @@ int const OWSLinkedDevicesTableViewControllerSectionAddDevice = 1;
|
||||
return (NSInteger)[self.deviceMappings numberOfItemsInSection:(NSUInteger)section];
|
||||
case OWSLinkedDevicesTableViewControllerSectionAddDevice:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
DDLogError(@"Unknown section: %ld", (long)section);
|
||||
return 0;
|
||||
|
||||
@ -12,9 +12,9 @@ extern uint32_t const OWSDevicePrimaryDeviceId;
|
||||
@interface OWSDevice : TSYapDatabaseObject <MTLJSONSerializing>
|
||||
|
||||
@property (nonatomic, readonly) NSInteger deviceId;
|
||||
@property (nullable, readonly) NSString *name;
|
||||
@property (readonly) NSDate *createdAt;
|
||||
@property (readonly) NSDate *lastSeenAt;
|
||||
@property (nonatomic, readonly, nullable) NSString *name;
|
||||
@property (nonatomic, readonly) NSDate *createdAt;
|
||||
@property (nonatomic, readonly) NSDate *lastSeenAt;
|
||||
|
||||
+ (instancetype)deviceFromJSONDictionary:(NSDictionary *)deviceAttributes error:(NSError **)error;
|
||||
|
||||
@ -52,6 +52,11 @@ extern uint32_t const OWSDevicePrimaryDeviceId;
|
||||
*/
|
||||
- (BOOL)updateAttributesWithDevice:(OWSDevice *)other;
|
||||
|
||||
#pragma mark - "May Have Linked Devices" Flag
|
||||
|
||||
+ (BOOL)mayHaveLinkedDevices:(YapDatabaseConnection *)dbConnection;
|
||||
+ (void)setMayHaveLinkedDevices:(BOOL)value dbConnection:(YapDatabaseConnection *)dbConnection;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -5,26 +5,29 @@
|
||||
#import "OWSDevice.h"
|
||||
#import "NSDate+OWS.h"
|
||||
#import "OWSError.h"
|
||||
#import "TSStorageManager.h"
|
||||
#import "YapDatabaseConnection.h"
|
||||
#import "YapDatabaseTransaction.h"
|
||||
#import <Mantle/MTLValueTransformer.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static MTLValueTransformer *_millisecondTimestampToDateTransformer;
|
||||
uint32_t const OWSDevicePrimaryDeviceId = 1;
|
||||
NSString *const kTSStorageManager_OWSDeviceCollection = @"kTSStorageManager_OWSDeviceCollection";
|
||||
NSString *const kTSStorageManager_MayHaveLinkedDevices = @"kTSStorageManager_MayHaveLinkedDevices";
|
||||
|
||||
@interface OWSDevice ()
|
||||
|
||||
@property NSString *name;
|
||||
@property NSDate *createdAt;
|
||||
@property NSDate *lastSeenAt;
|
||||
@property (nonatomic) NSInteger deviceId;
|
||||
@property (nonatomic, nullable) NSString *name;
|
||||
@property (nonatomic) NSDate *createdAt;
|
||||
@property (nonatomic) NSDate *lastSeenAt;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSDevice
|
||||
#pragma mark -
|
||||
|
||||
@synthesize name = _name;
|
||||
@implementation OWSDevice
|
||||
|
||||
+ (instancetype)deviceFromJSONDictionary:(NSDictionary *)deviceAttributes error:(NSError **)error
|
||||
{
|
||||
@ -76,38 +79,39 @@ uint32_t const OWSDevicePrimaryDeviceId = 1;
|
||||
|
||||
+ (MTLValueTransformer *)millisecondTimestampToDateTransformer
|
||||
{
|
||||
if (!_millisecondTimestampToDateTransformer) {
|
||||
_millisecondTimestampToDateTransformer =
|
||||
[MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError **error) {
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
NSNumber *number = (NSNumber *)value;
|
||||
NSDate *result = [NSDate ows_dateWithMillisecondsSince1970:[number longLongValue]];
|
||||
static MTLValueTransformer *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError **error) {
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
NSNumber *number = (NSNumber *)value;
|
||||
NSDate *result = [NSDate ows_dateWithMillisecondsSince1970:[number longLongValue]];
|
||||
if (result) {
|
||||
*success = YES;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
*success = NO;
|
||||
DDLogError(@"%@ unable to decode date from %@", self.logTag, value);
|
||||
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecodeJson, @"Unable to decode date from %@");
|
||||
return nil;
|
||||
}
|
||||
reverseBlock:^id(id value, BOOL *success, NSError **error) {
|
||||
if ([value isKindOfClass:[NSDate class]]) {
|
||||
NSDate *date = (NSDate *)value;
|
||||
NSNumber *result = [NSNumber numberWithLongLong:[NSDate ows_millisecondsSince1970ForDate:date]];
|
||||
if (result) {
|
||||
*success = YES;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
DDLogError(@"%@ unable to encode date from %@", self.logTag, value);
|
||||
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToEncodeJson, @"Unable to encode date");
|
||||
*success = NO;
|
||||
DDLogError(@"%@ unable to decode date from %@", self.logTag, value);
|
||||
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecodeJson, @"Unable to decode date from %@");
|
||||
return nil;
|
||||
}
|
||||
reverseBlock:^id(id value, BOOL *success, NSError **error) {
|
||||
if ([value isKindOfClass:[NSDate class]]) {
|
||||
NSDate *date = (NSDate *)value;
|
||||
NSNumber *result = [NSNumber numberWithLongLong:[NSDate ows_millisecondsSince1970ForDate:date]];
|
||||
if (result) {
|
||||
*success = YES;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
DDLogError(@"%@ unable to encode date from %@", self.logTag, value);
|
||||
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToEncodeJson, @"Unable to encode date");
|
||||
*success = NO;
|
||||
return nil;
|
||||
}];
|
||||
}
|
||||
return _millisecondTimestampToDateTransformer;
|
||||
}];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
+ (uint32_t)currentDeviceId
|
||||
@ -178,6 +182,26 @@ uint32_t const OWSDevicePrimaryDeviceId = 1;
|
||||
return self.deviceId == device.deviceId;
|
||||
}
|
||||
|
||||
#pragma mark - "May Have Linked Devices" Flag
|
||||
|
||||
+ (BOOL)mayHaveLinkedDevices:(YapDatabaseConnection *)dbConnection
|
||||
{
|
||||
OWSAssert(dbConnection);
|
||||
|
||||
return [dbConnection boolForKey:kTSStorageManager_MayHaveLinkedDevices
|
||||
inCollection:kTSStorageManager_OWSDeviceCollection
|
||||
defaultValue:YES];
|
||||
}
|
||||
|
||||
+ (void)setMayHaveLinkedDevices:(BOOL)value dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
{
|
||||
OWSAssert(dbConnection);
|
||||
|
||||
[dbConnection setBool:value
|
||||
forKey:kTSStorageManager_MayHaveLinkedDevices
|
||||
inCollection:kTSStorageManager_OWSDeviceCollection];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -971,15 +971,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||
// devices, then can safely skip sending sync message.
|
||||
|
||||
// 1. Check OWSDevice's state.
|
||||
__block BOOL hasSecondaryDevices;
|
||||
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
hasSecondaryDevices = [OWSDevice hasSecondaryDevicesWithTransaction:transaction];
|
||||
}];
|
||||
BOOL mayHaveLinkedDevices = [OWSDevice mayHaveLinkedDevices:self.dbConnection];
|
||||
|
||||
// 2. Check SignalRecipient's state.
|
||||
BOOL hasDeviceMessages = deviceMessages.count > 0;
|
||||
|
||||
if (!hasSecondaryDevices && !hasDeviceMessages) {
|
||||
if (!mayHaveLinkedDevices && !hasDeviceMessages) {
|
||||
DDLogInfo(@"%@ Ignoring sync message without secondary devices: %@", self.logTag, [message class]);
|
||||
OWSAssert([message isKindOfClass:[OWSOutgoingSyncMessage class]]);
|
||||
|
||||
@ -990,7 +987,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||
});
|
||||
|
||||
return;
|
||||
} else if (hasSecondaryDevices) {
|
||||
} else if (mayHaveLinkedDevices) {
|
||||
// We may have just linked a new secondary device which is not yet reflected in
|
||||
// the SignalRecipient that corresponds to ourself. Proceed. Client should learn
|
||||
// of new secondary devices via 409 "Mismatched devices" response.
|
||||
@ -1113,6 +1110,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||
NSArray *extraDevices = [dictionary objectForKey:@"extraDevices"];
|
||||
NSArray *missingDevices = [dictionary objectForKey:@"missingDevices"];
|
||||
|
||||
if (missingDevices.count > 0) {
|
||||
NSString *localNumber = [TSAccountManager localNumber];
|
||||
if ([localNumber isEqualToString:recipient.uniqueId]) {
|
||||
[OWSDevice setMayHaveLinkedDevices:YES dbConnection:self.dbConnection];
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sessionStoreQueue], ^{
|
||||
if (extraDevices.count < 1 && missingDevices.count < 1) {
|
||||
OWSProdFail([OWSAnalyticsEvents messageSenderErrorNoMissingOrExtraDevices]);
|
||||
|
||||
@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (BOOL)hasObjectForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||
- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||
- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue;
|
||||
- (int)intForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||
- (nullable id)objectForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||
- (nullable NSDate *)dateForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||
|
||||
@ -51,6 +51,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
|
||||
- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection
|
||||
{
|
||||
return [self boolForKey:key inCollection:collection defaultValue:NO];
|
||||
}
|
||||
|
||||
- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue
|
||||
{
|
||||
NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]];
|
||||
return [number boolValue];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user