Fixing leaky caches.

pull/1/head
Frederic Jacobs 10 years ago
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];
+ (BOOL)isMigratingTo2Dot0{
return [self userDefaultsBoolForKey: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];
[Environment.preferences setAndGetCurrentVersion];
[[NSUserDefaults standardUserDefaults] setObject:@YES forKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
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];
}
+ (BOOL)isMigratingTo2Dot0{
NSNumber *num = [[NSUserDefaults standardUserDefaults] objectForKey:IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY];
+ (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…
Cancel
Save