Fixing leaky caches.
This commit is contained in:
parent
89dd9efe05
commit
e47e9759e9
@ -25,7 +25,6 @@
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@property (nonatomic, retain) UIWindow *blankWindow;
|
||||
@ -36,32 +35,6 @@
|
||||
|
||||
#pragma mark Detect updates - perform migrations
|
||||
|
||||
- (void)performUpdateCheck{
|
||||
NSString *previousVersion = Environment.preferences.lastRanVersion;
|
||||
NSString *currentVersion = [Environment.preferences setAndGetCurrentVersion];
|
||||
BOOL isCurrentlyMigrating = [VersionMigrations isMigratingTo2Dot0];
|
||||
|
||||
if (!previousVersion) {
|
||||
DDLogError(@"No previous version found. Possibly first launch since install.");
|
||||
} else if(([self isVersion:previousVersion atLeast:@"1.0.2" andLessThan:@"2.0"]) || isCurrentlyMigrating) {
|
||||
[VersionMigrations migrateFrom1Dot0Dot2ToVersion2Dot0];
|
||||
} else if(([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.0.18"])) {
|
||||
[VersionMigrations migrateBloomFilter];
|
||||
}
|
||||
}
|
||||
|
||||
-(BOOL) isVersion:(NSString *)thisVersionString atLeast:(NSString *)openLowerBoundVersionString andLessThan:(NSString *)closedUpperBoundVersionString {
|
||||
return [self isVersion:thisVersionString atLeast:openLowerBoundVersionString] && [self isVersion:thisVersionString lessThan:closedUpperBoundVersionString];
|
||||
}
|
||||
|
||||
- (BOOL) isVersion:(NSString *)thisVersionString atLeast:(NSString *)thatVersionString {
|
||||
return [thisVersionString compare:thatVersionString options:NSNumericSearch] != NSOrderedAscending;
|
||||
}
|
||||
|
||||
- (BOOL) isVersion:(NSString *)thisVersionString lessThan:(NSString *)thatVersionString {
|
||||
return [thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedAscending;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
[self setupAppearance];
|
||||
|
||||
@ -104,7 +77,7 @@
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[self performUpdateCheck]; // this call must be made after environment has been initialized because in general upgrade may depend on environment
|
||||
[VersionMigrations performUpdateCheck]; // this call must be made after environment has been initialized because in general upgrade may depend on environment
|
||||
|
||||
//Accept push notification when app is not open
|
||||
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
|
||||
@ -12,11 +12,7 @@
|
||||
|
||||
@interface VersionMigrations : NSObject
|
||||
|
||||
+ (void)migrateBloomFilter;
|
||||
|
||||
+ (void)migrateFrom1Dot0Dot2ToVersion2Dot0;
|
||||
|
||||
+ (BOOL)isMigratingTo2Dot0;
|
||||
|
||||
+ (void)performUpdateCheck;
|
||||
+ (BOOL)isMigrating;
|
||||
|
||||
@end
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#import "TSDatabaseView.h"
|
||||
|
||||
#define IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY @"Migrating from 1.0 to Larger"
|
||||
#define NEEDS_TO_REGISTER_PUSH_KEY @"Register For Push"
|
||||
|
||||
|
||||
|
||||
@ -32,6 +33,61 @@
|
||||
|
||||
@implementation VersionMigrations
|
||||
|
||||
#pragma mark Utility methods
|
||||
|
||||
+ (void)performUpdateCheck{
|
||||
NSString *previousVersion = Environment.preferences.lastRanVersion;
|
||||
NSString *currentVersion = [Environment.preferences setAndGetCurrentVersion];
|
||||
BOOL isCurrentlyMigrating = [VersionMigrations isMigratingTo2Dot0];
|
||||
BOOL needsToRegisterPush = [VersionMigrations needsRegisterPush];
|
||||
|
||||
if (!previousVersion) {
|
||||
DDLogError(@"No previous version found. Possibly first launch since install.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(([self isVersion:previousVersion atLeast:@"1.0.2" andLessThan:@"2.0"]) || isCurrentlyMigrating) {
|
||||
[VersionMigrations migrateFrom1Dot0Dot2ToVersion2Dot0];
|
||||
}
|
||||
|
||||
if(([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.0.18"])) {
|
||||
[VersionMigrations migrateBloomFilter];
|
||||
}
|
||||
|
||||
if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.0.21"] || needsToRegisterPush) {
|
||||
[self clearVideoCache];
|
||||
[self blockingPushRegistration];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isMigrating{
|
||||
return [self isMigratingTo2Dot0];
|
||||
}
|
||||
|
||||
+ (BOOL) isVersion:(NSString *)thisVersionString atLeast:(NSString *)openLowerBoundVersionString andLessThan:(NSString *)closedUpperBoundVersionString {
|
||||
return [self isVersion:thisVersionString atLeast:openLowerBoundVersionString] && [self isVersion:thisVersionString lessThan:closedUpperBoundVersionString];
|
||||
}
|
||||
|
||||
+ (BOOL) isVersion:(NSString *)thisVersionString atLeast:(NSString *)thatVersionString {
|
||||
return [thisVersionString compare:thatVersionString options:NSNumericSearch] != NSOrderedAscending;
|
||||
}
|
||||
|
||||
+ (BOOL) isVersion:(NSString *)thisVersionString lessThan:(NSString *)thatVersionString {
|
||||
return [thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedAscending;
|
||||
}
|
||||
|
||||
+ (void)clearUserDefaults{
|
||||
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
|
||||
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
|
||||
|
||||
[Environment.preferences setAndGetCurrentVersion];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@YES forKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
#pragma mark 2.0.1
|
||||
|
||||
+ (void)migrateBloomFilter {
|
||||
// The bloom filter had to be moved to the cache folder after rejection of the 2.0.1
|
||||
NSString *oldBloomKey = @"Directory Bloom Data";
|
||||
@ -39,6 +95,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma mark 2.0
|
||||
|
||||
+ (void)migrateFrom1Dot0Dot2ToVersion2Dot0 {
|
||||
|
||||
if (!([self wasRedPhoneRegistered] || [self isMigratingTo2Dot0])) {
|
||||
@ -60,7 +118,7 @@
|
||||
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:waitingController animated:YES completion:nil];
|
||||
|
||||
[PushManager.sharedManager registrationAndRedPhoneTokenRequestWithSuccess:^(NSData *pushToken, NSData *voipToken, NSString *signupToken) {
|
||||
[TSAccountManager registerWithRedPhoneToken:signupToken pushToken:pushToken voipToken:voipToken success:^{
|
||||
[TSAccountManager registerWithRedPhoneToken:signupToken pushToken:pushToken voipToken:voipToken success:^{
|
||||
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:NO];
|
||||
[self clearMigrationFlag];
|
||||
Environment *env = [Environment getCurrent];
|
||||
@ -94,7 +152,6 @@
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark helper methods
|
||||
+ (void) migrateRecentCallsToVersion2Dot0 {
|
||||
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
|
||||
NSData *encodedData = [defaults objectForKey:RECENT_CALLS_DEFAULT_KEY];
|
||||
@ -158,17 +215,76 @@
|
||||
[UICKeyChainStore removeItemForKey:SIGNALING_EXTRA_KEY];
|
||||
}
|
||||
|
||||
+ (void)clearUserDefaults{
|
||||
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
|
||||
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
|
||||
|
||||
[Environment.preferences setAndGetCurrentVersion];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@YES forKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
+ (BOOL)isMigratingTo2Dot0{
|
||||
return [self userDefaultsBoolForKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
}
|
||||
|
||||
+ (BOOL)isMigratingTo2Dot0{
|
||||
NSNumber *num = [[NSUserDefaults standardUserDefaults] objectForKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
+ (void)clearMigrationFlag{
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
}
|
||||
|
||||
#pragma mark Upgrading to 2.1 - Needs to register VOIP token + Removing video cache folder
|
||||
|
||||
+ (void)blockingPushRegistration{
|
||||
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:YES];
|
||||
|
||||
UIAlertController *waitingController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Upgrading Signal ...", nil)
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:waitingController
|
||||
animated:YES
|
||||
completion:nil];
|
||||
|
||||
failedPushRegistrationBlock failure = ^(NSError *error) {
|
||||
[self refreshPushLock:waitingController];
|
||||
};
|
||||
|
||||
[[PushManager sharedManager] requestPushTokenWithSuccess:^(NSData *pushToken, NSData *voipToken) {
|
||||
[TSAccountManager registerForPushNotifications:pushToken voipToken:voipToken success:^{
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_PUSH_KEY];
|
||||
} failure:failure];
|
||||
} failure:failure];
|
||||
}
|
||||
|
||||
+ (void)refreshPushLock:(UIAlertController*)waitingController {
|
||||
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:NO];
|
||||
[waitingController dismissViewControllerAnimated:NO completion:^{
|
||||
UIAlertController *retryController = [UIAlertController alertControllerWithTitle:@"Upgrading Signal failed"
|
||||
message:@"An error occured while upgrading, please try again."
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[retryController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"REGISTER_FAILED_TRY_AGAIN", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[self blockingPushRegistration];
|
||||
}]];
|
||||
|
||||
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:retryController
|
||||
animated:YES
|
||||
completion:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (BOOL)needsRegisterPush {
|
||||
return [self userDefaultsBoolForKey:NEEDS_TO_REGISTER_PUSH_KEY];
|
||||
}
|
||||
|
||||
+ (void)clearVideoCache {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
|
||||
basePath = [basePath stringByAppendingPathComponent:@"videos"];
|
||||
|
||||
NSError *error;
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:basePath]){
|
||||
[NSFileManager.defaultManager removeItemAtPath:basePath error:&error];
|
||||
}
|
||||
DDLogError(@"An error occured while removing the videos cache folder from old location: %@",
|
||||
error.debugDescription);
|
||||
}
|
||||
|
||||
+ (BOOL)userDefaultsBoolForKey:(NSString*)key {
|
||||
NSNumber *num = [[NSUserDefaults standardUserDefaults] objectForKey:key];
|
||||
|
||||
if (!num) {
|
||||
return NO;
|
||||
@ -177,8 +293,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)clearMigrationFlag{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
self.operationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:textSecureServerURL] sessionConfiguration:sessionConf];
|
||||
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
|
||||
policy.allowInvalidCertificates = YES;
|
||||
policy.allowInvalidCertificates = YES; //The certificate is not signed by a CA in the iOS trust store.
|
||||
policy.validatesCertificateChain = NO; //Looking at AFNetworking's implementation of chain checking, we don't need to pin all certs in chain. https://github.com/AFNetworking/AFNetworking/blob/104ce04105098466ea0ea4e337af554d7b9df195/AFNetworking/AFSecurityPolicy.m#L281 Trust to the trusted cert is already vertified before by AFServerTrustIsValid();
|
||||
NSString *certPath = [NSBundle.mainBundle pathForResource:@"textsecure" ofType:@"cer"];
|
||||
|
||||
@ -81,16 +81,24 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass";
|
||||
- (void)protectSignalFiles{
|
||||
[self protectFolderAtPath:[TSAttachmentStream attachmentsFolder]];
|
||||
[self protectFolderAtPath:[self dbPath]];
|
||||
[self protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-shm"]];
|
||||
[self protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-wal"]];
|
||||
[self protectFolderAtPath:[[DebugLogger sharedInstance] logsDirectory]];
|
||||
}
|
||||
|
||||
- (void)protectFolderAtPath:(NSString*)path {
|
||||
if (![NSFileManager.defaultManager fileExistsAtPath:path]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *attrs = @{NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication,
|
||||
NSURLIsExcludedFromBackupKey:@YES};
|
||||
NSDictionary *fileProtection = @{NSFileProtectionKey:NSFileProtectionCompleteUntilFirstUserAuthentication};
|
||||
[[NSFileManager defaultManager] setAttributes:fileProtection ofItemAtPath:path error:&error];
|
||||
|
||||
NSDictionary *resourcesAttrs = @{NSURLIsExcludedFromBackupKey: @YES};
|
||||
|
||||
BOOL success = [NSFileManager.defaultManager setAttributes:attrs ofItemAtPath:path error:&error];
|
||||
NSURL *ressourceURL = [NSURL fileURLWithPath:path];
|
||||
BOOL success = [ressourceURL setResourceValues:resourcesAttrs error:&error];
|
||||
|
||||
if (error || !success) {
|
||||
DDLogError(@"Error while removing files from backup: %@", error.description);
|
||||
|
||||
@ -1196,28 +1196,34 @@ typedef enum : NSUInteger {
|
||||
}];
|
||||
}
|
||||
|
||||
-(void)sendQualityAdjustedAttachment:(NSURL*)movieURL {
|
||||
// TODO: should support anything that is in the videos directory
|
||||
AVAsset *video = [AVAsset assetWithURL:movieURL];
|
||||
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality];
|
||||
exportSession.shouldOptimizeForNetworkUse = YES;
|
||||
exportSession.outputFileType = AVFileTypeMPEG4;
|
||||
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
- (NSURL*)videoTempFolder {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
|
||||
basePath = [basePath stringByAppendingPathComponent:@"videos"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:basePath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
return [NSURL fileURLWithPath:basePath];
|
||||
}
|
||||
|
||||
-(void)sendQualityAdjustedAttachment:(NSURL*)movieURL {
|
||||
AVAsset *video = [AVAsset assetWithURL:movieURL];
|
||||
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality];
|
||||
exportSession.shouldOptimizeForNetworkUse = YES;
|
||||
exportSession.outputFileType = AVFileTypeMPEG4;
|
||||
|
||||
NSURL *compressedVideoUrl = [NSURL fileURLWithPath:basePath];
|
||||
double currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
NSString *strImageName = [NSString stringWithFormat:@"%f",currentTime];
|
||||
compressedVideoUrl = [compressedVideoUrl URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",strImageName]];
|
||||
NSURL *compressedVideoUrl = [[self videoTempFolder] URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",strImageName]];
|
||||
|
||||
exportSession.outputURL = compressedVideoUrl;
|
||||
[exportSession exportAsynchronouslyWithCompletionHandler:^{
|
||||
NSError *error;
|
||||
[self sendMessageAttachment:[NSData dataWithContentsOfURL:compressedVideoUrl] ofType:@"video/mp4"];
|
||||
[[NSFileManager defaultManager] removeItemAtURL:compressedVideoUrl error:&error];
|
||||
if (error) {
|
||||
DDLogWarn(@"Failed to remove cached video file: %@", error.debugDescription);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||
[super viewWillAppear:animated];
|
||||
[self checkIfEmptyView];
|
||||
|
||||
if (![TSAccountManager isRegistered] && ![VersionMigrations isMigratingTo2Dot0]){
|
||||
if (![TSAccountManager isRegistered] && ![VersionMigrations isMigrating]){
|
||||
[self performSegueWithIdentifier:kShowSignupFlowSegue sender:self];
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user