Merge branch 'charlesmchen/appExtensionMigration'
This commit is contained in:
commit
594544b264
|
@ -188,6 +188,6 @@ SPEC CHECKSUMS:
|
|||
YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266
|
||||
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
||||
|
||||
PODFILE CHECKSUM: 8e42a06de2d254e448580cfd6212545739de62d6
|
||||
PODFILE CHECKSUM: 558b99b22f87c7fb6e4a9c3084b14a384203d431
|
||||
|
||||
COCOAPODS: 1.3.1
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.default-data-protection</key>
|
||||
<string>NSFileProtectionComplete</string>
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
|
@ -16,5 +18,13 @@
|
|||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
</array>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.whispersystems.signal.group</string>
|
||||
</array>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)org.whispersystems.signal</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#import "VersionMigrations.h"
|
||||
#import "ViewControllerUtils.h"
|
||||
#import <AxolotlKit/SessionCipher.h>
|
||||
#import <SignalMessaging/SignalMessaging.h>
|
||||
#import <SignalServiceKit/NSUserDefaults+OWS.h>
|
||||
#import <SignalServiceKit/OWSBatchMessageProcessor.h>
|
||||
#import <SignalServiceKit/OWSDisappearingMessagesJob.h>
|
||||
#import <SignalServiceKit/OWSFailedAttachmentDownloadsJob.h>
|
||||
|
@ -38,7 +40,6 @@
|
|||
#import <SignalServiceKit/TSSocketManager.h>
|
||||
#import <SignalServiceKit/TSStorageManager+Calling.h>
|
||||
#import <SignalServiceKit/TextSecureKitEnv.h>
|
||||
#import <SignalMessaging/SignalMessaging.h>
|
||||
|
||||
@import WebRTC;
|
||||
@import Intents;
|
||||
|
@ -103,6 +104,19 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
DDLogWarn(@"%@ application: didFinishLaunchingWithOptions.", self.logTag);
|
||||
|
||||
// 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 (due to [NSUserDefaults migrateToSharedUserDefaults]), so honor
|
||||
// that change if necessary.
|
||||
if (loggingIsEnabled && !OWSPreferences.loggingIsEnabled) {
|
||||
[DebugLogger.sharedLogger disableFileLogging];
|
||||
}
|
||||
#endif
|
||||
|
||||
[AppVersion instance];
|
||||
|
||||
[self startupLogging];
|
||||
|
@ -176,6 +190,21 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)ensureIsReadyForAppExtensions
|
||||
{
|
||||
if ([OWSPreferences isReadyForAppExtensions]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[NSUserDefaults migrateToSharedUserDefaults];
|
||||
|
||||
[TSStorageManager migrateToSharedData];
|
||||
[OWSProfileManager migrateToSharedData];
|
||||
[TSAttachmentStream migrateToSharedData];
|
||||
|
||||
[OWSPreferences setIsReadyForAppExtensions:YES];
|
||||
}
|
||||
|
||||
- (void)startupLogging
|
||||
{
|
||||
DDLogInfo(@"iOS Version: %@", [UIDevice currentDevice].systemVersion);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1384,14 +1384,29 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
return image;
|
||||
}
|
||||
|
||||
+ (NSString *)legacyProfileAvatarsDirPath
|
||||
{
|
||||
return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
}
|
||||
|
||||
+ (NSString *)sharedDataProfileAvatarsDirPath
|
||||
{
|
||||
return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
}
|
||||
|
||||
+ (void)migrateToSharedData
|
||||
{
|
||||
[OWSFileSystem moveAppFilePath:self.legacyProfileAvatarsDirPath
|
||||
sharedDataFilePath:self.sharedDataProfileAvatarsDirPath
|
||||
exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"];
|
||||
}
|
||||
|
||||
- (NSString *)profileAvatarsDirPath
|
||||
{
|
||||
static NSString *profileAvatarsDirPath = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *documentsPath =
|
||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
||||
profileAvatarsDirPath = [documentsPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
profileAvatarsDirPath = OWSProfileManager.sharedDataProfileAvatarsDirPath;
|
||||
|
||||
BOOL isDirectory;
|
||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory];
|
||||
|
|
|
@ -27,6 +27,9 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog;
|
|||
|
||||
#pragma mark - Specific Preferences
|
||||
|
||||
+ (BOOL)isReadyForAppExtensions;
|
||||
+ (void)setIsReadyForAppExtensions:(BOOL)value;
|
||||
|
||||
- (BOOL)getHasSentAMessage;
|
||||
- (void)setHasSentAMessage:(BOOL)enabled;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#import "OWSPreferences.h"
|
||||
#import "TSStorageHeaders.h"
|
||||
#import <SignalServiceKit/NSUserDefaults+OWS.h>
|
||||
|
||||
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_IsReadyForAppExtensions = @"isReadyForAppExtensions";
|
||||
|
||||
@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)isReadyForAppExtensions
|
||||
{
|
||||
NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKey_IsReadyForAppExtensions];
|
||||
|
||||
if (preference) {
|
||||
return [preference boolValue];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setIsReadyForAppExtensions:(BOOL)value
|
||||
{
|
||||
[NSUserDefaults.appUserDefaults setObject:@(value) forKey:OWSPreferencesKey_IsReadyForAppExtensions];
|
||||
[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
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
#import "OWSDatabaseMigrationRunner.h"
|
||||
#import "PushManager.h"
|
||||
#import "SignalKeyingStorage.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import <SignalServiceKit/AppVersion.h>
|
||||
#import <SignalServiceKit/NSUserDefaults+OWS.h>
|
||||
#import <SignalServiceKit/TSAccountManager.h>
|
||||
#import <SignalServiceKit/TSNetworkManager.h>
|
||||
|
||||
#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];
|
||||
|
|
|
@ -57,6 +57,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
- (CGFloat)audioDurationSeconds;
|
||||
|
||||
+ (void)migrateToSharedData;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -180,14 +180,29 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return [dataSource writeToPath:filePath];
|
||||
}
|
||||
|
||||
+ (NSString *)legacyAttachmentsDirPath
|
||||
{
|
||||
return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"Attachments"];
|
||||
}
|
||||
|
||||
+ (NSString *)sharedDataAttachmentsDirPath
|
||||
{
|
||||
return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"Attachments"];
|
||||
}
|
||||
|
||||
+ (void)migrateToSharedData
|
||||
{
|
||||
[OWSFileSystem moveAppFilePath:self.legacyAttachmentsDirPath
|
||||
sharedDataFilePath:self.sharedDataAttachmentsDirPath
|
||||
exceptionName:@"CouldNotMigrateAttachmentsDirectory"];
|
||||
}
|
||||
|
||||
+ (NSString *)attachmentsFolder
|
||||
{
|
||||
static NSString *attachmentsFolder = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *documentsPath =
|
||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
||||
attachmentsFolder = [documentsPath stringByAppendingPathComponent:@"Attachments"];
|
||||
attachmentsFolder = TSAttachmentStream.sharedDataAttachmentsDirPath;
|
||||
|
||||
BOOL isDirectory;
|
||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory];
|
||||
|
|
|
@ -63,9 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
|
||||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
|
||||
|
||||
#pragma mark - Utilities
|
||||
|
||||
- (void)protectFolderAtPath:(NSString *)path;
|
||||
+ (void)migrateToSharedData;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
@ -202,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;
|
||||
}
|
||||
|
@ -231,7 +237,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 +259,7 @@ void setDatabaseInitialized()
|
|||
options.cipherKeyBlock = ^{
|
||||
return databasePassword;
|
||||
};
|
||||
options.enableMultiProcessSupport = YES;
|
||||
|
||||
#ifdef DEBUG
|
||||
_database = [[OWSDatabase alloc] initWithPath:[self dbPath]
|
||||
|
@ -349,10 +356,16 @@ void setDatabaseInitialized()
|
|||
[TSDatabaseView asyncRegistrationCompletion];
|
||||
}
|
||||
|
||||
- (void)protectSignalFiles {
|
||||
[OWSFileSystem protectFolderAtPath:[self dbPath]];
|
||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-shm"]];
|
||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-wal"]];
|
||||
+ (void)protectSignalFiles
|
||||
{
|
||||
// The old database location was in the Document directory,
|
||||
// so protect the database files individually.
|
||||
[OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath];
|
||||
[OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath_SHM];
|
||||
[OWSFileSystem protectFolderAtPath:self.legacyDatabaseFilePath_WAL];
|
||||
|
||||
// Protect the entire new database directory.
|
||||
[OWSFileSystem protectFolderAtPath:self.sharedDataDatabaseDirPath];
|
||||
}
|
||||
|
||||
- (nullable YapDatabaseConnection *)newDatabaseConnection
|
||||
|
@ -364,33 +377,99 @@ void setDatabaseInitialized()
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
- (BOOL)dbExists {
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:[self dbPath]];
|
||||
+ (NSString *)legacyDatabaseDirPath
|
||||
{
|
||||
return [OWSFileSystem appDocumentDirectoryPath];
|
||||
}
|
||||
|
||||
- (NSString *)dbPath {
|
||||
NSString *databasePath;
|
||||
+ (NSString *)sharedDataDatabaseDirPath
|
||||
{
|
||||
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
|
||||
|
||||
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
|
||||
NSArray *urlPaths = [fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
|
||||
|
||||
NSURL *appDirectory = [[urlPaths objectAtIndex:0] URLByAppendingPathComponent:bundleID isDirectory:YES];
|
||||
|
||||
if (![fileManager fileExistsAtPath:[appDirectory path]]) {
|
||||
[fileManager createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:nil];
|
||||
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;
|
||||
}
|
||||
|
||||
databasePath = [appDirectory.filePathURL.absoluteString stringByAppendingPathComponent:databaseName];
|
||||
#endif
|
||||
+ (NSString *)databaseFilename
|
||||
{
|
||||
return @"Signal.sqlite";
|
||||
}
|
||||
|
||||
return databasePath;
|
||||
+ (NSString *)databaseFilename_SHM
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-shm"];
|
||||
}
|
||||
|
||||
+ (NSString *)databaseFilename_WAL
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-wal"];
|
||||
}
|
||||
|
||||
+ (NSString *)legacyDatabaseFilePath
|
||||
{
|
||||
return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||
}
|
||||
|
||||
+ (NSString *)legacyDatabaseFilePath_SHM
|
||||
{
|
||||
return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||
}
|
||||
|
||||
+ (NSString *)legacyDatabaseFilePath_WAL
|
||||
{
|
||||
return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||
}
|
||||
|
||||
+ (NSString *)sharedDataDatabaseFilePath
|
||||
{
|
||||
return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||
}
|
||||
|
||||
+ (NSString *)sharedDataDatabaseFilePath_SHM
|
||||
{
|
||||
return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||
}
|
||||
|
||||
+ (NSString *)sharedDataDatabaseFilePath_WAL
|
||||
{
|
||||
return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||
}
|
||||
|
||||
+ (void)migrateToSharedData
|
||||
{
|
||||
[OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath
|
||||
sharedDataFilePath:self.sharedDataDatabaseFilePath
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
[OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_SHM
|
||||
sharedDataFilePath:self.sharedDataDatabaseFilePath_SHM
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
[OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_WAL
|
||||
sharedDataFilePath:self.sharedDataDatabaseFilePath_WAL
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
}
|
||||
|
||||
- (NSString *)dbPath
|
||||
{
|
||||
DDLogVerbose(@"databasePath: %@", TSStorageManager.sharedDataDatabaseFilePath);
|
||||
|
||||
return TSStorageManager.sharedDataDatabaseFilePath;
|
||||
}
|
||||
|
||||
+ (BOOL)isDatabasePasswordAccessible
|
||||
|
@ -421,7 +500,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 +562,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.");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
|
||||
#import "AppVersion.h"
|
||||
#import <SignalServiceKit/NSUserDefaults+OWS.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSUserDefaults+OWS.h"
|
||||
#import "TSConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation NSUserDefaults (OWS)
|
||||
|
||||
+ (NSUserDefaults *)appUserDefaults
|
||||
{
|
||||
return [[NSUserDefaults alloc] initWithSuiteName:SignalApplicationGroup];
|
||||
}
|
||||
|
||||
+ (void)migrateToSharedUserDefaults
|
||||
{
|
||||
NSUserDefaults *appUserDefaults = self.appUserDefaults;
|
||||
|
||||
NSDictionary<NSString *, id> *dictionary = [NSUserDefaults standardUserDefaults].dictionaryRepresentation;
|
||||
for (NSString *key in dictionary) {
|
||||
id value = dictionary[key];
|
||||
OWSAssert(value);
|
||||
[appUserDefaults setObject:value forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)removeAll
|
||||
{
|
||||
[NSUserDefaults.standardUserDefaults removeAll];
|
||||
[self.appUserDefaults removeAll];
|
||||
}
|
||||
|
||||
- (void)removeAll
|
||||
{
|
||||
NSDictionary<NSString *, id> *dictionary = self.dictionaryRepresentation;
|
||||
for (NSString *key in dictionary) {
|
||||
[self removeObjectForKey:key];
|
||||
}
|
||||
[self synchronize];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -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
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
|
||||
#import "OWSFileSystem.h"
|
||||
#import "TSConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -28,6 +29,59 @@ 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:SignalApplicationGroup];
|
||||
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]) {
|
||||
OWSFail(@"%@ Can't move file or directory from %@ to %@; destination already exists.",
|
||||
self.logTag,
|
||||
oldFilePath,
|
||||
newFilePath);
|
||||
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 file or directory 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
|
||||
|
|
Loading…
Reference in New Issue