diff --git a/Pods b/Pods index 414616b861..7c5cd466ad 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 414616b861fdc81aaac5d437905eda95b7facd1f +Subproject commit 7c5cd466ada8524ddea3b3d9b0fe2f734b882a04 diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index a471fb279f..c2e69c0e74 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -49,7 +49,7 @@ CFBundleVersion - 2.32.0.5 + 2.32.0.8 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index daa8f2ce5b..5f29c6e770 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -90,6 +90,8 @@ @import Photos; +//#define FEATURE_FLAG_ALBUM_SEND_ENABLED; + NS_ASSUME_NONNULL_BEGIN static const CGFloat kLoadMoreHeaderHeight = 60.f; @@ -2638,10 +2640,17 @@ typedef enum : NSUInteger { return; } +#ifdef FEATURE_FLAG_ALBUM_SEND_ENABLED OWSImagePickerGridController *picker = [OWSImagePickerGridController new]; picker.delegate = self; OWSNavigationController *pickerModal = [[OWSNavigationController alloc] initWithRootViewController:picker]; +#else + UIImagePickerController *pickerModal = [UIImagePickerController new]; + pickerModal.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; + pickerModal.delegate = self; + pickerModal.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ]; +#endif [self dismissKeyBoard]; [self presentViewController:pickerModal animated:YES completion:nil]; @@ -2711,7 +2720,7 @@ typedef enum : NSUInteger { NSString *mediaType = info[UIImagePickerControllerMediaType]; if ([mediaType isEqualToString:(__bridge NSString *)kUTTypeMovie]) { - // Video captured with camera + // Video picked from library or captured with camera NSURL *videoURL = info[UIImagePickerControllerMediaURL]; [self dismissViewControllerAnimated:YES @@ -2749,8 +2758,60 @@ typedef enum : NSUInteger { } }]; } else { + // Non-Video image picked from library +#ifdef FEATURE_FLAG_ALBUM_SEND_ENABLED OWSFailDebug( @"Only use UIImagePicker for camera/video capture. Picking media from UIImagePicker is not supported. "); +#endif + + // To avoid re-encoding GIF and PNG's as JPEG we have to get the raw data of + // the selected item vs. using the UIImagePickerControllerOriginalImage + NSURL *assetURL = info[UIImagePickerControllerReferenceURL]; + PHAsset *asset = [[PHAsset fetchAssetsWithALAssetURLs:@[ assetURL ] options:nil] lastObject]; + if (!asset) { + return failedToPickAttachment(nil); + } + + // Images chosen from the "attach document" UI should be sent as originals; + // images chosen from the "attach media" UI should be resized to "medium" size; + TSImageQuality imageQuality = (self.isPickingMediaAsDocument ? TSImageQualityOriginal : TSImageQualityMedium); + + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; + options.synchronous = YES; // We're only fetching one asset. + options.networkAccessAllowed = YES; // iCloud OK + options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; // Don't need quick/dirty version + [[PHImageManager defaultManager] + requestImageDataForAsset:asset + options:options + resultHandler:^(NSData *_Nullable imageData, + NSString *_Nullable dataUTI, + UIImageOrientation orientation, + NSDictionary *_Nullable assetInfo) { + NSError *assetFetchingError = assetInfo[PHImageErrorKey]; + if (assetFetchingError || !imageData) { + return failedToPickAttachment(assetFetchingError); + } + OWSAssertIsOnMainThread(); + + DataSource *_Nullable dataSource = + [DataSourceValue dataSourceWithData:imageData utiType:dataUTI]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource + dataUTI:dataUTI + imageQuality:imageQuality]; + [self dismissViewControllerAnimated:YES + completion:^{ + OWSAssertIsOnMainThread(); + if (!attachment || [attachment hasError]) { + OWSLogWarn(@"Invalid attachment: %@.", + attachment ? [attachment errorName] : @"Missing data"); + [self showErrorAlertForAttachment:attachment]; + failedToPickAttachment(nil); + } else { + [self tryToSendAttachmentIfApproved:attachment]; + } + }]; + }]; } } diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.m b/SignalServiceKit/src/Contacts/SignalRecipient.m index 2e8853e3a2..6f2c576c09 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.m +++ b/SignalServiceKit/src/Contacts/SignalRecipient.m @@ -71,23 +71,8 @@ NS_ASSUME_NONNULL_BEGIN if (!self) { return self; } - - OWSAssertDebug(self.tsAccountManager.localNumber.length > 0); - if ([self.tsAccountManager.localNumber isEqualToString:textSecureIdentifier]) { - // Default to no devices. - // - // This instance represents our own account and is used for sending - // sync message to linked devices. We shouldn't have any linked devices - // yet when we create the "self" SignalRecipient, and we don't need to - // send sync messages to the primary - we ARE the primary. - _devices = [NSOrderedSet new]; - } else { - // Default to sending to just primary device. - // - // OWSMessageSender will correct this if it is wrong the next time - // we send a message to this recipient. - _devices = [NSOrderedSet orderedSetWithObject:@(OWSDevicePrimaryDeviceId)]; - } + + _devices = [NSOrderedSet orderedSetWithObject:@(OWSDevicePrimaryDeviceId)]; return self; } @@ -103,9 +88,13 @@ NS_ASSUME_NONNULL_BEGIN _devices = [NSOrderedSet new]; } - if ([self.uniqueId isEqual:self.tsAccountManager.localNumber] && - [self.devices containsObject:@(OWSDevicePrimaryDeviceId)]) { - OWSFailDebug(@"self as recipient device"); + // Since we use device count to determine whether a user is registered or not, + // ensure the local user always has at least *this* device. + if (![_devices containsObject:@(OWSDevicePrimaryDeviceId)]) { + if ([self.uniqueId isEqualToString:self.tsAccountManager.localNumber]) { + DDLogInfo(@"Adding primary device to self recipient."); + [self addDevices:[NSSet setWithObject:@(OWSDevicePrimaryDeviceId)]]; + } } return self; @@ -129,12 +118,6 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssertDebug(devices.count > 0); - if ([self.uniqueId isEqual:self.tsAccountManager.localNumber] && - [devices containsObject:@(OWSDevicePrimaryDeviceId)]) { - OWSFailDebug(@"adding self as recipient device"); - return; - } - NSMutableOrderedSet *updatedDevices = [self.devices mutableCopy]; [updatedDevices unionSet:devices]; self.devices = [updatedDevices copy]; diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 8d715fa472..36fc8e8ed7 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -819,8 +819,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; }]; } -- (nullable NSArray *)deviceMessagesForMessageSendSafe:(OWSMessageSend *)messageSend - error:(NSError **)errorHandle +- (nullable NSArray *)deviceMessagesForMessageSend:(OWSMessageSend *)messageSend + error:(NSError **)errorHandle { OWSAssertDebug(messageSend); OWSAssertDebug(errorHandle); @@ -830,7 +830,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSArray *deviceMessages; @try { - deviceMessages = [self throws_deviceMessagesForMessageSendUnsafe:messageSend]; + deviceMessages = [self throws_deviceMessagesForMessageSend:messageSend]; } @catch (NSException *exception) { if ([exception.name isEqualToString:UntrustedIdentityKeyException]) { // This *can* happen under normal usage, but it should happen relatively rarely. @@ -964,7 +964,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSError *deviceMessagesError; NSArray *_Nullable deviceMessages = - [self deviceMessagesForMessageSendSafe:messageSend error:&deviceMessagesError]; + [self deviceMessagesForMessageSend:messageSend error:&deviceMessagesError]; if (deviceMessagesError || !deviceMessages) { OWSAssertDebug(deviceMessagesError); return messageSend.failure(deviceMessagesError); @@ -1398,7 +1398,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self sendMessageToRecipient:messageSend]; } -- (NSArray *)throws_deviceMessagesForMessageSendUnsafe:(OWSMessageSend *)messageSend +- (NSArray *)throws_deviceMessagesForMessageSend:(OWSMessageSend *)messageSend { OWSAssertDebug(messageSend.message); OWSAssertDebug(messageSend.recipient); @@ -1423,11 +1423,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSMutableArray *deviceIds = [recipient.devices mutableCopy]; OWSAssertDebug(deviceIds); - if (messageSend.isUDSend && messageSend.isLocalNumber) { - OWSLogVerbose(@"Adding device message for UD send to local device."); - OWSAssertDebug(![deviceIds containsObject:@(OWSDevicePrimaryDeviceId)]); - - [deviceIds addObject:@(OWSDevicePrimaryDeviceId)]; + if (messageSend.isLocalNumber) { + [deviceIds removeObject:@(OWSDevicePrimaryDeviceId)]; } for (NSNumber *deviceId in deviceIds) { diff --git a/SignalServiceKit/tests/Contacts/SignalRecipientTest.m b/SignalServiceKit/tests/Contacts/SignalRecipientTest.m index 630719613a..ea92dab366 100644 --- a/SignalServiceKit/tests/Contacts/SignalRecipientTest.m +++ b/SignalServiceKit/tests/Contacts/SignalRecipientTest.m @@ -2,10 +2,10 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "SignalRecipient.h" #import "MockSSKEnvironment.h" #import "OWSPrimaryStorage.h" #import "SSKBaseTestObjC.h" +#import "SignalRecipient.h" #import "TSAccountManager.h" #import "TestAppContext.h" #import @@ -49,4 +49,16 @@ }]; } +- (void)testRecipientWithExistingRecord +{ + // Sanity Check + XCTAssertNotNil(self.localNumber); + NSString *recipientId = @"+15551231234"; + [self readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [SignalRecipient markRecipientAsRegisteredAndGet:recipientId transaction:transaction]; + + XCTAssertTrue([SignalRecipient isRegisteredRecipient:recipientId transaction:transaction]); + }]; +} + @end diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index b11943ca07..bd48afbbd8 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.32.0 CFBundleVersion - 2.32.0.5 + 2.32.0.8 ITSAppUsesNonExemptEncryption NSAppTransportSecurity