From cd11ec56987021ba5c4863457fbf21ea80c83c33 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 28 Nov 2017 13:03:38 -0500 Subject: [PATCH 1/5] Add app group, share keychain. Take a first pass at file migration to shared data directory. --- Signal.xcodeproj/project.pbxproj | 6 + Signal/Signal.entitlements | 10 ++ Signal/src/Profiles/OWSProfileManager.m | 14 +- .../Messages/Attachments/TSAttachmentStream.m | 14 +- .../src/Storage/TSStorageManager.h | 4 - .../src/Storage/TSStorageManager.m | 154 ++++++++++++++---- SignalServiceKit/src/Util/OWSFileSystem.h | 8 + SignalServiceKit/src/Util/OWSFileSystem.m | 50 ++++++ 8 files changed, 221 insertions(+), 39 deletions(-) diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 29fef9e46..5ba2b140a 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -2052,6 +2052,9 @@ LastSwiftMigration = 0800; ProvisioningStyle = Automatic; SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; com.apple.DataProtection = { enabled = 1; }; @@ -2061,6 +2064,9 @@ com.apple.InterAppAudio = { enabled = 0; }; + com.apple.Keychain = { + enabled = 1; + }; com.apple.Push = { enabled = 1; }; diff --git a/Signal/Signal.entitlements b/Signal/Signal.entitlements index dfec421ea..79da5ce67 100644 --- a/Signal/Signal.entitlements +++ b/Signal/Signal.entitlements @@ -4,6 +4,8 @@ aps-environment development + com.apple.developer.default-data-protection + NSFileProtectionComplete com.apple.developer.icloud-container-identifiers iCloud.$(CFBundleIdentifier) @@ -16,5 +18,13 @@ iCloud.$(CFBundleIdentifier) + com.apple.security.application-groups + + group.org.whispersystems.signal.group + + keychain-access-groups + + $(AppIdentifierPrefix)org.whispersystems.signal + diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index cc0737759..ba6fe9109 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -1389,9 +1389,17 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; static NSString *profileAvatarsDirPath = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentsPath = - [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - profileAvatarsDirPath = [documentsPath stringByAppendingPathComponent:@"ProfileAvatars"]; + NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; + NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; + + NSString *oldProfileAvatarsDirPath = [documentDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; + NSString *newProfileAvatarsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; + + [OWSFileSystem moveAppFilePath:oldProfileAvatarsDirPath + sharedDataFilePath:newProfileAvatarsDirPath + exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; + + profileAvatarsDirPath = newProfileAvatarsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index 5c6a74003..a40b62ee5 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -185,9 +185,17 @@ NS_ASSUME_NONNULL_BEGIN static NSString *attachmentsFolder = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentsPath = - [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - attachmentsFolder = [documentsPath stringByAppendingPathComponent:@"Attachments"]; + NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; + NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; + + NSString *oldAttachmentsDirPath = [documentDirPath stringByAppendingPathComponent:@"Attachments"]; + NSString *newAttachmentsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"Attachments"]; + + [OWSFileSystem moveAppFilePath:oldAttachmentsDirPath + sharedDataFilePath:newAttachmentsDirPath + exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; + + attachmentsFolder = newAttachmentsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Storage/TSStorageManager.h b/SignalServiceKit/src/Storage/TSStorageManager.h index b8e5f0007..0dbd4ad4a 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.h +++ b/SignalServiceKit/src/Storage/TSStorageManager.h @@ -63,10 +63,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection; @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; -#pragma mark - Utilities - -- (void)protectFolderAtPath:(NSString *)path; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index fb9fe3c65..dbe9d99b1 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -24,13 +24,18 @@ NS_ASSUME_NONNULL_BEGIN -NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessible = @"TSStorageManagerExceptionNameDatabasePasswordInaccessible"; -NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded = - @"TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded"; -NSString *const TSStorageManagerExceptionNameDatabasePasswordUnwritable = @"TSStorageManagerExceptionNameDatabasePasswordUnwritable"; -NSString *const TSStorageManagerExceptionNameNoDatabase = @"TSStorageManagerExceptionNameNoDatabase"; +NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessible + = @"TSStorageManagerExceptionName_DatabasePasswordInaccessible"; +NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded + = @"TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded"; +NSString *const TSStorageManagerExceptionName_DatabasePasswordUnwritable + = @"TSStorageManagerExceptionName_DatabasePasswordUnwritable"; +NSString *const TSStorageManagerExceptionName_NoDatabase = @"TSStorageManagerExceptionName_NoDatabase"; +NSString *const TSStorageManagerExceptionName_CouldNotMoveDatabaseFile + = @"TSStorageManagerExceptionName_CouldNotMoveDatabaseFile"; +NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory + = @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory"; -static const NSString *const databaseName = @"Signal.sqlite"; static NSString *keychainService = @"TSKeyChainService"; static NSString *keychainDBPassAccount = @"TSDatabasePass"; @@ -231,7 +236,7 @@ void setDatabaseInitialized() // Sleep to give analytics events time to be delivered. [NSThread sleepForTimeInterval:15.0f]; - [NSException raise:TSStorageManagerExceptionNameNoDatabase format:@"Failed to initialize database."]; + [NSException raise:TSStorageManagerExceptionName_NoDatabase format:@"Failed to initialize database."]; } OWSSingletonAssert(); @@ -253,6 +258,7 @@ void setDatabaseInitialized() options.cipherKeyBlock = ^{ return databasePassword; }; + options.enableMultiProcessSupport = YES; #ifdef DEBUG _database = [[OWSDatabase alloc] initWithPath:[self dbPath] @@ -350,9 +356,14 @@ void setDatabaseInitialized() } - (void)protectSignalFiles { - [OWSFileSystem protectFolderAtPath:[self dbPath]]; - [OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-shm"]]; - [OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-wal"]]; + // The old database location was in the Document directory, + // so protect the database files individually. + [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]]; + [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_SHM]]; + [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_WAL]]; + + // Protect the entire new database directory. + [OWSFileSystem protectFolderAtPath:[self newDatabaseDirPath]]; } - (nullable YapDatabaseConnection *)newDatabaseConnection @@ -364,33 +375,118 @@ void setDatabaseInitialized() return FALSE; } -- (BOOL)dbExists { - return [[NSFileManager defaultManager] fileExistsAtPath:[self dbPath]]; +- (NSString *)oldDatabaseDirPath +{ + return [OWSFileSystem appDocumentDirectoryPath]; } -- (NSString *)dbPath { - NSString *databasePath; +- (NSString *)newDatabaseDirPath +{ + NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; NSFileManager *fileManager = [NSFileManager defaultManager]; -#if TARGET_OS_IPHONE - NSURL *fileURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; - NSString *path = [fileURL path]; - databasePath = [path stringByAppendingPathComponent:databaseName]; -#elif TARGET_OS_MAC + if (![fileManager fileExistsAtPath:databaseDirPath]) { + NSError *_Nullable error; + BOOL success = [fileManager createDirectoryAtPath:databaseDirPath + withIntermediateDirectories:NO + attributes:nil + error:&error]; + if (!success || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"%@ Could not create new database directory: %@, error: %@", + self.logTag, + databaseDirPath, + error]; + OWSFail(@"%@", errorDescription); + [NSException raise:TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory + format:@"%@", errorDescription]; + } + } + return databaseDirPath; +} - NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; - NSArray *urlPaths = [fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]; +- (NSString *)databaseFilename +{ + return @"Signal.sqlite"; +} - NSURL *appDirectory = [[urlPaths objectAtIndex:0] URLByAppendingPathComponent:bundleID isDirectory:YES]; +- (NSString *)databaseFilename_SHM +{ + return [self.databaseFilename stringByAppendingString:@"-shm"]; +} - if (![fileManager fileExistsAtPath:[appDirectory path]]) { - [fileManager createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:nil]; +- (NSString *)databaseFilename_WAL +{ + return [self.databaseFilename stringByAppendingString:@"-wal"]; +} + +- (NSString *)oldDatabaseFilePath +{ + return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; +} + +- (NSString *)oldDatabaseFilePath_SHM +{ + return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; +} + +- (NSString *)oldDatabaseFilePath_WAL +{ + return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; +} + +- (NSString *)newDatabaseFilePath +{ + return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; +} + +- (NSString *)newDatabaseFilePath_SHM +{ + return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; +} + +- (NSString *)newDatabaseFilePath_WAL +{ + return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; +} + +- (NSString *)dbPath +{ + [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath + sharedDataFilePath:self.newDatabaseFilePath + exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; + [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_SHM + sharedDataFilePath:self.newDatabaseFilePath_SHM + exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; + [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_WAL + sharedDataFilePath:self.newDatabaseFilePath_WAL + exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL hasAllNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] && + [fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] && + [fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]); + BOOL hasAnyNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] || + [fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] || + [fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]); + if (!hasAllNewFiles && !hasAnyNewFiles) { + for (NSString *filePath in @[ + self.newDatabaseFilePath, + self.newDatabaseFilePath_SHM, + self.newDatabaseFilePath_WAL, + self.newDatabaseFilePath, + self.newDatabaseFilePath_SHM, + self.newDatabaseFilePath_WAL, + ]) { + DDLogInfo(@"%@ Database file %@ exists %d", self.logTag, filePath, [fileManager fileExistsAtPath:filePath]); + } + OWSFail(@"%@ Incomplete set of database files.", self.logTag); } - databasePath = [appDirectory.filePathURL.absoluteString stringByAppendingPathComponent:databaseName]; -#endif + DDLogError(@"databasePath: %@", self.newDatabaseFilePath); + [DDLog flushLog]; - return databasePath; + return self.newDatabaseFilePath; } + (BOOL)isDatabasePasswordAccessible @@ -421,7 +517,7 @@ void setDatabaseInitialized() // Presumably this happened in response to a push notification. It's possible that the keychain is corrupted // but it could also just be that the user hasn't yet unlocked their device since our password is // kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly - [NSException raise:TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded + [NSException raise:TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded format:@"%@", errorDescription]; } @@ -483,7 +579,7 @@ void setDatabaseInitialized() // Sleep to give analytics events time to be delivered. [NSThread sleepForTimeInterval:15.0f]; - [NSException raise:TSStorageManagerExceptionNameDatabasePasswordUnwritable + [NSException raise:TSStorageManagerExceptionName_DatabasePasswordUnwritable format:@"Setting DB password failed with error: %@", keySetError]; } else { DDLogWarn(@"Succesfully set new DB password."); diff --git a/SignalServiceKit/src/Util/OWSFileSystem.h b/SignalServiceKit/src/Util/OWSFileSystem.h index 3eae177bb..b9abd6a5d 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.h +++ b/SignalServiceKit/src/Util/OWSFileSystem.h @@ -10,6 +10,14 @@ NS_ASSUME_NONNULL_BEGIN + (void)protectFolderAtPath:(NSString *)path; ++ (NSString *)appDocumentDirectoryPath; + ++ (NSString *)appSharedDataDirectoryPath; + ++ (void)moveAppFilePath:(NSString *)oldFilePath + sharedDataFilePath:(NSString *)newFilePath + exceptionName:(NSString *)exceptionName; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/OWSFileSystem.m b/SignalServiceKit/src/Util/OWSFileSystem.m index 6e69eb0e2..1d77559ad 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.m +++ b/SignalServiceKit/src/Util/OWSFileSystem.m @@ -28,6 +28,56 @@ NS_ASSUME_NONNULL_BEGIN } } ++ (NSString *)appDocumentDirectoryPath +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *documentDirectoryURL = + [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; + return [documentDirectoryURL path]; +} + ++ (NSString *)appSharedDataDirectoryPath +{ + NSURL *groupContainerDirectoryURL = [[NSFileManager defaultManager] + containerURLForSecurityApplicationGroupIdentifier:@"group.org.whispersystems.signal.group"]; + return [groupContainerDirectoryURL path]; +} + ++ (void)moveAppFilePath:(NSString *)oldFilePath + sharedDataFilePath:(NSString *)newFilePath + exceptionName:(NSString *)exceptionName +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + if (![fileManager fileExistsAtPath:oldFilePath]) { + return; + } + if ([fileManager fileExistsAtPath:newFilePath]) { + DDLogError(@""); + return; + } + + NSDate *startDate = [NSDate new]; + + NSError *_Nullable error; + BOOL success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error]; + if (!success || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"%@ Could not move database file from %@ to %@, error: %@", + self.logTag, + oldFilePath, + newFilePath, + error]; + OWSFail(@"%@", errorDescription); + [NSException raise:exceptionName format:@"%@", errorDescription]; + } + + DDLogInfo(@"%@ Moving file or directory from %@ to %@ in: %f", + self.logTag, + oldFilePath, + newFilePath, + fabs([startDate timeIntervalSinceNow])); +} + @end NS_ASSUME_NONNULL_END From edaf65223a034d32c08108b05b5fe56ea2cbfa22 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 28 Nov 2017 13:46:26 -0500 Subject: [PATCH 2/5] Migrate to shared data NSUserDefaults. --- Signal/src/AppDelegate.m | 28 +++++++++ Signal/src/Profiles/OWSProfileManager.h | 2 + Signal/src/Profiles/OWSProfileManager.m | 29 +++++---- Signal/src/environment/OWSPreferences.h | 3 + Signal/src/environment/OWSPreferences.m | 30 ++++++--- Signal/src/environment/VersionMigrations.m | 47 +++++++------- .../Messages/Attachments/TSAttachmentStream.h | 2 + .../Messages/Attachments/TSAttachmentStream.m | 29 +++++---- .../src/Storage/TSStorageManager.h | 2 + .../src/Storage/TSStorageManager.m | 61 +++++++------------ SignalServiceKit/src/Util/AppVersion.m | 21 +++---- .../src/Util/NSUserDefaults+OWS.h | 17 ++++++ .../src/Util/NSUserDefaults+OWS.m | 37 +++++++++++ 13 files changed, 206 insertions(+), 102 deletions(-) create mode 100644 SignalServiceKit/src/Util/NSUserDefaults+OWS.h create mode 100644 SignalServiceKit/src/Util/NSUserDefaults+OWS.m diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5f2707044..1607ffdd9 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -24,6 +24,7 @@ #import "VersionMigrations.h" #import "ViewControllerUtils.h" #import +#import #import #import #import @@ -103,6 +104,18 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; DDLogWarn(@"%@ application: didFinishLaunchingWithOptions.", self.logTag); + // We need to this _after_ we set up logging but _before_ we do + // anything else. + [self ensureMigrationToSharedData]; + +#if RELEASE + // ensureMigrationToSharedData may have changed the state of the logging + // preference, so honor that change if necessary. + if (loggingIsEnabled && !OWSPreferences.loggingIsEnabled) { + [DebugLogger.sharedLogger disableFileLogging]; + } +#endif + [AppVersion instance]; [self startupLogging]; @@ -176,6 +189,21 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return YES; } +- (void)ensureMigrationToSharedData +{ + if ([OWSPreferences hasMigratedToSharedData]) { + return; + } + + [NSUserDefaults migrateToSharedUserDefaults]; + + [TSStorageManager migrateToSharedData]; + [OWSProfileManager migrateToSharedData]; + [TSAttachmentStream migrateToSharedData]; + + [OWSPreferences setHasMigratedToSharedData:YES]; +} + - (void)startupLogging { DDLogInfo(@"iOS Version: %@", [UIDevice currentDevice].systemVersion); diff --git a/Signal/src/Profiles/OWSProfileManager.h b/Signal/src/Profiles/OWSProfileManager.h index 3d67415f0..331dddb23 100644 --- a/Signal/src/Profiles/OWSProfileManager.h +++ b/Signal/src/Profiles/OWSProfileManager.h @@ -29,6 +29,8 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter; - (void)resetProfileStorage; ++ (void)migrateToSharedData; + #pragma mark - Local Profile // These two methods should only be called from the main thread. diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index ba6fe9109..2cef339a7 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -1384,22 +1384,29 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; return image; } ++ (NSString *)oldProfileAvatarsDirPath +{ + return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; +} + ++ (NSString *)newProfileAvatarsDirPath +{ + return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; +} + ++ (void)migrateToSharedData +{ + [OWSFileSystem moveAppFilePath:self.oldProfileAvatarsDirPath + sharedDataFilePath:self.newProfileAvatarsDirPath + exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; +} + - (NSString *)profileAvatarsDirPath { static NSString *profileAvatarsDirPath = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; - NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; - - NSString *oldProfileAvatarsDirPath = [documentDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; - NSString *newProfileAvatarsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; - - [OWSFileSystem moveAppFilePath:oldProfileAvatarsDirPath - sharedDataFilePath:newProfileAvatarsDirPath - exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; - - profileAvatarsDirPath = newProfileAvatarsDirPath; + profileAvatarsDirPath = OWSProfileManager.newProfileAvatarsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory]; diff --git a/Signal/src/environment/OWSPreferences.h b/Signal/src/environment/OWSPreferences.h index 27a0d674c..822f9fe4d 100644 --- a/Signal/src/environment/OWSPreferences.h +++ b/Signal/src/environment/OWSPreferences.h @@ -27,6 +27,9 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog; #pragma mark - Specific Preferences ++ (BOOL)hasMigratedToSharedData; ++ (void)setHasMigratedToSharedData:(BOOL)value; + - (BOOL)getHasSentAMessage; - (void)setHasSentAMessage:(BOOL)enabled; diff --git a/Signal/src/environment/OWSPreferences.m b/Signal/src/environment/OWSPreferences.m index 6e7e66467..c7fa02d3c 100644 --- a/Signal/src/environment/OWSPreferences.m +++ b/Signal/src/environment/OWSPreferences.m @@ -4,6 +4,7 @@ #import "OWSPreferences.h" #import "TSStorageHeaders.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -22,6 +23,7 @@ NSString *const OWSPreferencesKeyCallKitPrivacyEnabled = @"CallKitPrivacyEnabled NSString *const OWSPreferencesKeyCallsHideIPAddress = @"CallsHideIPAddress"; NSString *const OWSPreferencesKeyHasDeclinedNoContactsView = @"hasDeclinedNoContactsView"; NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; +NSString *const OWSPreferencesKey_HasMigratedToSharedData = @"hasMigratedToSharedData"; @implementation OWSPreferences @@ -40,10 +42,7 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; #pragma mark - Helpers - (void)clear { - @synchronized(self) { - NSString *appDomain = NSBundle.mainBundle.bundleIdentifier; - [NSUserDefaults.standardUserDefaults removePersistentDomainForName:appDomain]; - } + [NSUserDefaults removeAll]; } - (nullable id)tryGetValueForKey:(NSString *)key @@ -61,6 +60,23 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; #pragma mark - Specific Preferences ++ (BOOL)hasMigratedToSharedData +{ + NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKey_HasMigratedToSharedData]; + + if (preference) { + return [preference boolValue]; + } else { + return NO; + } +} + ++ (void)setHasMigratedToSharedData:(BOOL)value +{ + [NSUserDefaults.appUserDefaults setObject:@(value) forKey:OWSPreferencesKey_HasMigratedToSharedData]; + [NSUserDefaults.appUserDefaults synchronize]; +} + - (BOOL)screenSecurityIsEnabled { NSNumber *preference = [self tryGetValueForKey:OWSPreferencesKeyScreenSecurity]; @@ -94,7 +110,7 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; + (BOOL)loggingIsEnabled { - NSNumber *preference = [NSUserDefaults.standardUserDefaults objectForKey:OWSPreferencesKeyEnableDebugLog]; + NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKeyEnableDebugLog]; if (preference) { return [preference boolValue]; @@ -108,8 +124,8 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; // Logging preferences are stored in UserDefaults instead of the database, so that we can (optionally) start // logging before the database is initialized. This is important because sometimes there are problems *with* the // database initialization, and without logging it would be hard to track down. - [NSUserDefaults.standardUserDefaults setObject:@(flag) forKey:OWSPreferencesKeyEnableDebugLog]; - [NSUserDefaults.standardUserDefaults synchronize]; + [NSUserDefaults.appUserDefaults setObject:@(flag) forKey:OWSPreferencesKeyEnableDebugLog]; + [NSUserDefaults.appUserDefaults synchronize]; } - (void)setHasSentAMessage:(BOOL)enabled diff --git a/Signal/src/environment/VersionMigrations.m b/Signal/src/environment/VersionMigrations.m index 5afe4810d..ebf2caf29 100644 --- a/Signal/src/environment/VersionMigrations.m +++ b/Signal/src/environment/VersionMigrations.m @@ -8,9 +8,10 @@ #import "OWSDatabaseMigrationRunner.h" #import "PushManager.h" #import "SignalKeyingStorage.h" -#import "TSAccountManager.h" -#import "TSNetworkManager.h" #import +#import +#import +#import #define NEEDS_TO_REGISTER_PUSH_KEY @"Register For Push" #define NEEDS_TO_REGISTER_ATTRIBUTES @"Register Attributes" @@ -125,39 +126,39 @@ + (void)blockingAttributesUpdate { LIControllerBlockingOperation blockingOperation = ^BOOL(void) { - [[NSUserDefaults standardUserDefaults] setObject:@YES forKey:NEEDS_TO_REGISTER_ATTRIBUTES]; + [[NSUserDefaults appUserDefaults] setObject:@YES forKey:NEEDS_TO_REGISTER_ATTRIBUTES]; - __block dispatch_semaphore_t sema = dispatch_semaphore_create(0); + __block dispatch_semaphore_t sema = dispatch_semaphore_create(0); - __block BOOL success; + __block BOOL success; - TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithManualMessageFetching:NO]; - [[TSNetworkManager sharedManager] makeRequest:request - success:^(NSURLSessionDataTask *task, id responseObject) { - success = YES; - dispatch_semaphore_signal(sema); - } - failure:^(NSURLSessionDataTask *task, NSError *error) { - if (!IsNSErrorNetworkFailure(error)) { - OWSProdError([OWSAnalyticsEvents errorUpdateAttributesRequestFailed]); - } - success = NO; - DDLogError(@"Updating attributess failed with error: %@", error.description); - dispatch_semaphore_signal(sema); - }]; + TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithManualMessageFetching:NO]; + [[TSNetworkManager sharedManager] makeRequest:request + success:^(NSURLSessionDataTask *task, id responseObject) { + success = YES; + dispatch_semaphore_signal(sema); + } + failure:^(NSURLSessionDataTask *task, NSError *error) { + if (!IsNSErrorNetworkFailure(error)) { + OWSProdError([OWSAnalyticsEvents errorUpdateAttributesRequestFailed]); + } + success = NO; + DDLogError(@"Updating attributess failed with error: %@", error.description); + dispatch_semaphore_signal(sema); + }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); - return success; + return success; }; LIControllerRetryBlock retryBlock = [LockInteractionController defaultNetworkRetry]; [LockInteractionController performBlock:blockingOperation completionBlock:^{ - [[NSUserDefaults standardUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_ATTRIBUTES]; - DDLogWarn(@"Successfully updated attributes."); + [[NSUserDefaults appUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_ATTRIBUTES]; + DDLogWarn(@"Successfully updated attributes."); } retryBlock:retryBlock usesNetwork:YES]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index ac8f9c490..21cd8eb98 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -57,6 +57,8 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)audioDurationSeconds; ++ (void)migrateToSharedData; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index a40b62ee5..187ad5498 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -180,22 +180,29 @@ NS_ASSUME_NONNULL_BEGIN return [dataSource writeToPath:filePath]; } ++ (NSString *)oldAttachmentsDirPath +{ + return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; +} + ++ (NSString *)newAttachmentsDirPath +{ + return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; +} + ++ (void)migrateToSharedData +{ + [OWSFileSystem moveAppFilePath:self.oldAttachmentsDirPath + sharedDataFilePath:self.newAttachmentsDirPath + exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; +} + + (NSString *)attachmentsFolder { static NSString *attachmentsFolder = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; - NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; - - NSString *oldAttachmentsDirPath = [documentDirPath stringByAppendingPathComponent:@"Attachments"]; - NSString *newAttachmentsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"Attachments"]; - - [OWSFileSystem moveAppFilePath:oldAttachmentsDirPath - sharedDataFilePath:newAttachmentsDirPath - exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; - - attachmentsFolder = newAttachmentsDirPath; + attachmentsFolder = TSAttachmentStream.newAttachmentsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Storage/TSStorageManager.h b/SignalServiceKit/src/Storage/TSStorageManager.h index 0dbd4ad4a..38ce97988 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.h +++ b/SignalServiceKit/src/Storage/TSStorageManager.h @@ -63,6 +63,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection; @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; ++ (void)migrateToSharedData; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index dbe9d99b1..a4b18c3ae 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -207,10 +207,11 @@ void setDatabaseInitialized() static TSStorageManager *sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - sharedManager = [[self alloc] initDefault]; #if TARGET_OS_IPHONE - [sharedManager protectSignalFiles]; + [TSStorageManager protectSignalFiles]; #endif + + sharedManager = [[self alloc] initDefault]; }); return sharedManager; } @@ -355,7 +356,8 @@ void setDatabaseInitialized() [TSDatabaseView asyncRegistrationCompletion]; } -- (void)protectSignalFiles { ++ (void)protectSignalFiles +{ // The old database location was in the Document directory, // so protect the database files individually. [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]]; @@ -375,12 +377,12 @@ void setDatabaseInitialized() return FALSE; } -- (NSString *)oldDatabaseDirPath ++ (NSString *)oldDatabaseDirPath { return [OWSFileSystem appDocumentDirectoryPath]; } -- (NSString *)newDatabaseDirPath ++ (NSString *)newDatabaseDirPath { NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; @@ -405,52 +407,52 @@ void setDatabaseInitialized() return databaseDirPath; } -- (NSString *)databaseFilename ++ (NSString *)databaseFilename { return @"Signal.sqlite"; } -- (NSString *)databaseFilename_SHM ++ (NSString *)databaseFilename_SHM { return [self.databaseFilename stringByAppendingString:@"-shm"]; } -- (NSString *)databaseFilename_WAL ++ (NSString *)databaseFilename_WAL { return [self.databaseFilename stringByAppendingString:@"-wal"]; } -- (NSString *)oldDatabaseFilePath ++ (NSString *)oldDatabaseFilePath { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -- (NSString *)oldDatabaseFilePath_SHM ++ (NSString *)oldDatabaseFilePath_SHM { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -- (NSString *)oldDatabaseFilePath_WAL ++ (NSString *)oldDatabaseFilePath_WAL { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } -- (NSString *)newDatabaseFilePath ++ (NSString *)newDatabaseFilePath { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -- (NSString *)newDatabaseFilePath_SHM ++ (NSString *)newDatabaseFilePath_SHM { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -- (NSString *)newDatabaseFilePath_WAL ++ (NSString *)newDatabaseFilePath_WAL { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } -- (NSString *)dbPath ++ (void)migrateToSharedData { [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath sharedDataFilePath:self.newDatabaseFilePath @@ -461,32 +463,13 @@ void setDatabaseInitialized() [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_WAL sharedDataFilePath:self.newDatabaseFilePath_WAL exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; +} - NSFileManager *fileManager = [NSFileManager defaultManager]; - BOOL hasAllNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] && - [fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] && - [fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]); - BOOL hasAnyNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] || - [fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] || - [fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]); - if (!hasAllNewFiles && !hasAnyNewFiles) { - for (NSString *filePath in @[ - self.newDatabaseFilePath, - self.newDatabaseFilePath_SHM, - self.newDatabaseFilePath_WAL, - self.newDatabaseFilePath, - self.newDatabaseFilePath_SHM, - self.newDatabaseFilePath_WAL, - ]) { - DDLogInfo(@"%@ Database file %@ exists %d", self.logTag, filePath, [fileManager fileExistsAtPath:filePath]); - } - OWSFail(@"%@ Incomplete set of database files.", self.logTag); - } - - DDLogError(@"databasePath: %@", self.newDatabaseFilePath); - [DDLog flushLog]; +- (NSString *)dbPath +{ + DDLogVerbose(@"databasePath: %@", TSStorageManager.newDatabaseFilePath); - return self.newDatabaseFilePath; + return TSStorageManager.newDatabaseFilePath; } + (BOOL)isDatabasePasswordAccessible diff --git a/SignalServiceKit/src/Util/AppVersion.m b/SignalServiceKit/src/Util/AppVersion.m index 44fc99807..2c5dd8815 100755 --- a/SignalServiceKit/src/Util/AppVersion.m +++ b/SignalServiceKit/src/Util/AppVersion.m @@ -3,6 +3,7 @@ // #import "AppVersion.h" +#import NSString *const kNSUserDefaults_FirstAppVersion = @"kNSUserDefaults_FirstAppVersion"; NSString *const kNSUserDefaults_LastAppVersion = @"kNSUserDefaults_LastVersion"; @@ -36,24 +37,22 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion = @"kNSUserDefault // The version of the app when it was first launched. // nil if the app has never been launched before. - self.firstAppVersion = [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_FirstAppVersion]; + self.firstAppVersion = [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_FirstAppVersion]; // The version of the app the last time it was launched. // nil if the app has never been launched before. - self.lastAppVersion = [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_LastAppVersion]; + self.lastAppVersion = [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_LastAppVersion]; self.lastCompletedLaunchAppVersion = - [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; + [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; // Ensure the value for the "first launched version". if (!self.firstAppVersion) { self.firstAppVersion = self.currentAppVersion; - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_FirstAppVersion]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_FirstAppVersion]; } // Update the value for the "most recently launched version". - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_LastAppVersion]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_LastAppVersion]; + [[NSUserDefaults appUserDefaults] synchronize]; DDLogInfo(@"%@ firstAppVersion: %@", self.logTag, self.firstAppVersion); DDLogInfo(@"%@ lastAppVersion: %@", self.logTag, self.lastAppVersion); @@ -68,9 +67,9 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion = @"kNSUserDefault self.lastCompletedLaunchAppVersion = self.currentAppVersion; // Update the value for the "most recently launch-completed version". - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion + forKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; + [[NSUserDefaults appUserDefaults] synchronize]; } - (BOOL)isFirstLaunch diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.h b/SignalServiceKit/src/Util/NSUserDefaults+OWS.h new file mode 100644 index 000000000..24bbbcbc2 --- /dev/null +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.h @@ -0,0 +1,17 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@interface NSUserDefaults (OWS) + ++ (NSUserDefaults *)appUserDefaults; + ++ (void)migrateToSharedUserDefaults; + ++ (void)removeAll; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m new file mode 100644 index 000000000..1bff0e3e3 --- /dev/null +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m @@ -0,0 +1,37 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "NSUserDefaults+OWS.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSUserDefaults (OWS) + ++ (NSUserDefaults *)appUserDefaults +{ + return [[NSUserDefaults alloc] initWithSuiteName:@"group.org.whispersystems.signal.group"]; +} + ++ (void)migrateToSharedUserDefaults +{ + NSUserDefaults *appUserDefaults = self.appUserDefaults; + + NSDictionary *dictionary = [NSUserDefaults standardUserDefaults].dictionaryRepresentation; + for (NSString *key in dictionary) { + id value = dictionary[key]; + OWSAssert(value); + [appUserDefaults setObject:value forKey:key]; + } +} + ++ (void)removeAll +{ + NSString *appDomain = NSBundle.mainBundle.bundleIdentifier; + [NSUserDefaults.standardUserDefaults removePersistentDomainForName:appDomain]; + // TODO: How to clear the shared user defaults? +} + +@end + +NS_ASSUME_NONNULL_END From 7429e1968c278e6907251c6dbf5bc25b104a2261 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 28 Nov 2017 16:30:08 -0500 Subject: [PATCH 3/5] Clean up ahead of PR. --- Signal/src/AppDelegate.m | 10 +++++----- Signal/src/environment/OWSPreferences.h | 4 ++-- Signal/src/environment/OWSPreferences.m | 10 +++++----- SignalServiceKit/src/TSConstants.h | 2 ++ SignalServiceKit/src/Util/NSUserDefaults+OWS.m | 3 ++- SignalServiceKit/src/Util/OWSFileSystem.m | 18 ++++++++++-------- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 1607ffdd9..f537ff8aa 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -106,10 +106,10 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; // We need to this _after_ we set up logging but _before_ we do // anything else. - [self ensureMigrationToSharedData]; + [self ensureIsReadyForAppExtensions]; #if RELEASE - // ensureMigrationToSharedData may have changed the state of the logging + // ensureIsReadyForAppExtensions may have changed the state of the logging // preference, so honor that change if necessary. if (loggingIsEnabled && !OWSPreferences.loggingIsEnabled) { [DebugLogger.sharedLogger disableFileLogging]; @@ -189,9 +189,9 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return YES; } -- (void)ensureMigrationToSharedData +- (void)ensureIsReadyForAppExtensions { - if ([OWSPreferences hasMigratedToSharedData]) { + if ([OWSPreferences isReadyForAppExtensions]) { return; } @@ -201,7 +201,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; [OWSProfileManager migrateToSharedData]; [TSAttachmentStream migrateToSharedData]; - [OWSPreferences setHasMigratedToSharedData:YES]; + [OWSPreferences setIsReadyForAppExtensions:YES]; } - (void)startupLogging diff --git a/Signal/src/environment/OWSPreferences.h b/Signal/src/environment/OWSPreferences.h index 822f9fe4d..6a0cb1882 100644 --- a/Signal/src/environment/OWSPreferences.h +++ b/Signal/src/environment/OWSPreferences.h @@ -27,8 +27,8 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog; #pragma mark - Specific Preferences -+ (BOOL)hasMigratedToSharedData; -+ (void)setHasMigratedToSharedData:(BOOL)value; ++ (BOOL)isReadyForAppExtensions; ++ (void)setIsReadyForAppExtensions:(BOOL)value; - (BOOL)getHasSentAMessage; - (void)setHasSentAMessage:(BOOL)enabled; diff --git a/Signal/src/environment/OWSPreferences.m b/Signal/src/environment/OWSPreferences.m index c7fa02d3c..8548715f8 100644 --- a/Signal/src/environment/OWSPreferences.m +++ b/Signal/src/environment/OWSPreferences.m @@ -23,7 +23,7 @@ NSString *const OWSPreferencesKeyCallKitPrivacyEnabled = @"CallKitPrivacyEnabled NSString *const OWSPreferencesKeyCallsHideIPAddress = @"CallsHideIPAddress"; NSString *const OWSPreferencesKeyHasDeclinedNoContactsView = @"hasDeclinedNoContactsView"; NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; -NSString *const OWSPreferencesKey_HasMigratedToSharedData = @"hasMigratedToSharedData"; +NSString *const OWSPreferencesKey_IsReadyForAppExtensions = @"isReadyForAppExtensions"; @implementation OWSPreferences @@ -60,9 +60,9 @@ NSString *const OWSPreferencesKey_HasMigratedToSharedData = @"hasMigratedToShare #pragma mark - Specific Preferences -+ (BOOL)hasMigratedToSharedData ++ (BOOL)isReadyForAppExtensions { - NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKey_HasMigratedToSharedData]; + NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKey_IsReadyForAppExtensions]; if (preference) { return [preference boolValue]; @@ -71,9 +71,9 @@ NSString *const OWSPreferencesKey_HasMigratedToSharedData = @"hasMigratedToShare } } -+ (void)setHasMigratedToSharedData:(BOOL)value ++ (void)setIsReadyForAppExtensions:(BOOL)value { - [NSUserDefaults.appUserDefaults setObject:@(value) forKey:OWSPreferencesKey_HasMigratedToSharedData]; + [NSUserDefaults.appUserDefaults setObject:@(value) forKey:OWSPreferencesKey_IsReadyForAppExtensions]; [NSUserDefaults.appUserDefaults synchronize]; } diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index cefd281a0..717e2e0fc 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -57,6 +57,8 @@ typedef enum { kSMSVerification, kPhoneNumberVerification } VerificationTranspor #define textSecureSetProfileNameAPIFormat @"v1/profile/name/%@" #define textSecureProfileAvatarFormAPI @"v1/profile/form/avatar" +#define SignalApplicationGroup @"group.org.whispersystems.signal.group" + #pragma mark Push RegistrationSpecific Constants typedef NS_ENUM(NSInteger, TSPushRegistrationError) { TSPushRegistrationErrorNetwork, diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m index 1bff0e3e3..923ada8e1 100644 --- a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m @@ -3,6 +3,7 @@ // #import "NSUserDefaults+OWS.h" +#import "TSConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -10,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN + (NSUserDefaults *)appUserDefaults { - return [[NSUserDefaults alloc] initWithSuiteName:@"group.org.whispersystems.signal.group"]; + return [[NSUserDefaults alloc] initWithSuiteName:SignalApplicationGroup]; } + (void)migrateToSharedUserDefaults diff --git a/SignalServiceKit/src/Util/OWSFileSystem.m b/SignalServiceKit/src/Util/OWSFileSystem.m index 1d77559ad..551387b93 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.m +++ b/SignalServiceKit/src/Util/OWSFileSystem.m @@ -3,6 +3,7 @@ // #import "OWSFileSystem.h" +#import "TSConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -38,8 +39,8 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)appSharedDataDirectoryPath { - NSURL *groupContainerDirectoryURL = [[NSFileManager defaultManager] - containerURLForSecurityApplicationGroupIdentifier:@"group.org.whispersystems.signal.group"]; + NSURL *groupContainerDirectoryURL = + [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:SignalApplicationGroup]; return [groupContainerDirectoryURL path]; } @@ -52,7 +53,8 @@ NS_ASSUME_NONNULL_BEGIN return; } if ([fileManager fileExistsAtPath:newFilePath]) { - DDLogError(@""); + OWSFail( + @"%@ Can't move file from %@ to %@; destination already exists.", self.logTag, oldFilePath, newFilePath); return; } @@ -62,11 +64,11 @@ NS_ASSUME_NONNULL_BEGIN BOOL success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error]; if (!success || error) { NSString *errorDescription = - [NSString stringWithFormat:@"%@ Could not move database file from %@ to %@, error: %@", - self.logTag, - oldFilePath, - newFilePath, - error]; + [NSString stringWithFormat:@"%@ Could not move file or directory from %@ to %@, error: %@", + self.logTag, + oldFilePath, + newFilePath, + error]; OWSFail(@"%@", errorDescription); [NSException raise:exceptionName format:@"%@", errorDescription]; } From 779e89fe7477b7f0671938a88b17ccd033628fb4 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 29 Nov 2017 10:10:41 -0500 Subject: [PATCH 4/5] Clean up ahead of PR. --- SignalServiceKit/src/Util/OWSFileSystem.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Util/OWSFileSystem.m b/SignalServiceKit/src/Util/OWSFileSystem.m index 551387b93..8746b1443 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.m +++ b/SignalServiceKit/src/Util/OWSFileSystem.m @@ -53,8 +53,10 @@ NS_ASSUME_NONNULL_BEGIN return; } if ([fileManager fileExistsAtPath:newFilePath]) { - OWSFail( - @"%@ Can't move file from %@ to %@; destination already exists.", self.logTag, oldFilePath, newFilePath); + OWSFail(@"%@ Can't move file or directory from %@ to %@; destination already exists.", + self.logTag, + oldFilePath, + newFilePath); return; } From 8d4e9b4565d801c2bc08b29a0fb0c29fce2b30fb Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 30 Nov 2017 10:02:04 -0500 Subject: [PATCH 5/5] Respond to CR. --- Podfile.lock | 2 +- Signal/src/AppDelegate.m | 7 +-- Signal/src/Profiles/OWSProfileManager.m | 10 ++-- .../Messages/Attachments/TSAttachmentStream.m | 10 ++-- .../src/Storage/TSStorageManager.m | 52 +++++++++---------- .../src/Util/NSUserDefaults+OWS.m | 14 +++-- 6 files changed, 52 insertions(+), 43 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index bebd66947..d38989028 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -188,6 +188,6 @@ SPEC CHECKSUMS: YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266 YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 -PODFILE CHECKSUM: 8e42a06de2d254e448580cfd6212545739de62d6 +PODFILE CHECKSUM: 558b99b22f87c7fb6e4a9c3084b14a384203d431 COCOAPODS: 1.3.1 diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index f537ff8aa..fff346c7c 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -24,6 +24,7 @@ #import "VersionMigrations.h" #import "ViewControllerUtils.h" #import +#import #import #import #import @@ -39,7 +40,6 @@ #import #import #import -#import @import WebRTC; @import Intents; @@ -104,13 +104,14 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; DDLogWarn(@"%@ application: didFinishLaunchingWithOptions.", self.logTag); - // We need to this _after_ we set up logging but _before_ we do + // We need to do this _after_ we set up logging but _before_ we do // anything else. [self ensureIsReadyForAppExtensions]; #if RELEASE // ensureIsReadyForAppExtensions may have changed the state of the logging - // preference, so honor that change if necessary. + // preference (due to [NSUserDefaults migrateToSharedUserDefaults]), so honor + // that change if necessary. if (loggingIsEnabled && !OWSPreferences.loggingIsEnabled) { [DebugLogger.sharedLogger disableFileLogging]; } diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 2cef339a7..8c05020f7 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -1384,20 +1384,20 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; return image; } -+ (NSString *)oldProfileAvatarsDirPath ++ (NSString *)legacyProfileAvatarsDirPath { return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; } -+ (NSString *)newProfileAvatarsDirPath ++ (NSString *)sharedDataProfileAvatarsDirPath { return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; } + (void)migrateToSharedData { - [OWSFileSystem moveAppFilePath:self.oldProfileAvatarsDirPath - sharedDataFilePath:self.newProfileAvatarsDirPath + [OWSFileSystem moveAppFilePath:self.legacyProfileAvatarsDirPath + sharedDataFilePath:self.sharedDataProfileAvatarsDirPath exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; } @@ -1406,7 +1406,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; static NSString *profileAvatarsDirPath = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - profileAvatarsDirPath = OWSProfileManager.newProfileAvatarsDirPath; + profileAvatarsDirPath = OWSProfileManager.sharedDataProfileAvatarsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index 187ad5498..390f6b9d0 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -180,20 +180,20 @@ NS_ASSUME_NONNULL_BEGIN return [dataSource writeToPath:filePath]; } -+ (NSString *)oldAttachmentsDirPath ++ (NSString *)legacyAttachmentsDirPath { return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; } -+ (NSString *)newAttachmentsDirPath ++ (NSString *)sharedDataAttachmentsDirPath { return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; } + (void)migrateToSharedData { - [OWSFileSystem moveAppFilePath:self.oldAttachmentsDirPath - sharedDataFilePath:self.newAttachmentsDirPath + [OWSFileSystem moveAppFilePath:self.legacyAttachmentsDirPath + sharedDataFilePath:self.sharedDataAttachmentsDirPath exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; } @@ -202,7 +202,7 @@ NS_ASSUME_NONNULL_BEGIN static NSString *attachmentsFolder = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - attachmentsFolder = TSAttachmentStream.newAttachmentsDirPath; + attachmentsFolder = TSAttachmentStream.sharedDataAttachmentsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index a4b18c3ae..5a2dd722c 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -360,12 +360,12 @@ void setDatabaseInitialized() { // The old database location was in the Document directory, // so protect the database files individually. - [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]]; - [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_SHM]]; - [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_WAL]]; + [OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath]; + [OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath_SHM]; + [OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath_WAL]; // Protect the entire new database directory. - [OWSFileSystem protectFolderAtPath:[self newDatabaseDirPath]]; + [OWSFileSystem protectFolderAtPath:self.sharedDataDatabaseDirPath]; } - (nullable YapDatabaseConnection *)newDatabaseConnection @@ -377,12 +377,12 @@ void setDatabaseInitialized() return FALSE; } -+ (NSString *)oldDatabaseDirPath ++ (NSString *)legacyDatabaseDirPath { return [OWSFileSystem appDocumentDirectoryPath]; } -+ (NSString *)newDatabaseDirPath ++ (NSString *)sharedDataDatabaseDirPath { NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; @@ -422,54 +422,54 @@ void setDatabaseInitialized() return [self.databaseFilename stringByAppendingString:@"-wal"]; } -+ (NSString *)oldDatabaseFilePath ++ (NSString *)legacyDatabaseFilePath { - return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; + return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -+ (NSString *)oldDatabaseFilePath_SHM ++ (NSString *)legacyDatabaseFilePath_SHM { - return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; + return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -+ (NSString *)oldDatabaseFilePath_WAL ++ (NSString *)legacyDatabaseFilePath_WAL { - return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; + return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } -+ (NSString *)newDatabaseFilePath ++ (NSString *)sharedDataDatabaseFilePath { - return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; + return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -+ (NSString *)newDatabaseFilePath_SHM ++ (NSString *)sharedDataDatabaseFilePath_SHM { - return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; + return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -+ (NSString *)newDatabaseFilePath_WAL ++ (NSString *)sharedDataDatabaseFilePath_WAL { - return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; + return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } + (void)migrateToSharedData { - [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath - sharedDataFilePath:self.newDatabaseFilePath + [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath + sharedDataFilePath:self.sharedDataDatabaseFilePath exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; - [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_SHM - sharedDataFilePath:self.newDatabaseFilePath_SHM + [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_SHM + sharedDataFilePath:self.sharedDataDatabaseFilePath_SHM exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; - [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_WAL - sharedDataFilePath:self.newDatabaseFilePath_WAL + [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_WAL + sharedDataFilePath:self.sharedDataDatabaseFilePath_WAL exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile]; } - (NSString *)dbPath { - DDLogVerbose(@"databasePath: %@", TSStorageManager.newDatabaseFilePath); + DDLogVerbose(@"databasePath: %@", TSStorageManager.sharedDataDatabaseFilePath); - return TSStorageManager.newDatabaseFilePath; + return TSStorageManager.sharedDataDatabaseFilePath; } + (BOOL)isDatabasePasswordAccessible diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m index 923ada8e1..746630d0e 100644 --- a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m @@ -28,9 +28,17 @@ NS_ASSUME_NONNULL_BEGIN + (void)removeAll { - NSString *appDomain = NSBundle.mainBundle.bundleIdentifier; - [NSUserDefaults.standardUserDefaults removePersistentDomainForName:appDomain]; - // TODO: How to clear the shared user defaults? + [NSUserDefaults.standardUserDefaults removeAll]; + [self.appUserDefaults removeAll]; +} + +- (void)removeAll +{ + NSDictionary *dictionary = self.dictionaryRepresentation; + for (NSString *key in dictionary) { + [self removeObjectForKey:key]; + } + [self synchronize]; } @end