Rework thread safety in profile manager.
This commit is contained in:
parent
c1d435c9d8
commit
911c4d380b
@ -107,6 +107,8 @@
|
||||
3478506A1FD9B78A007B8332 /* AppSetup.h in Headers */ = {isa = PBXBuildFile; fileRef = 347850661FD9B789007B8332 /* AppSetup.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
3478506B1FD9B78A007B8332 /* NoopCallMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347850671FD9B78A007B8332 /* NoopCallMessageHandler.swift */; };
|
||||
3478506C1FD9B78A007B8332 /* NoopNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */; };
|
||||
347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 3478506F1FDAEB16007B8332 /* OWSUserProfile.m */; };
|
||||
347850721FDAEB17007B8332 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 347850701FDAEB16007B8332 /* OWSUserProfile.h */; };
|
||||
3497DBEC1ECE257500DB2605 /* OWSCountryMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */; };
|
||||
3497DBEF1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEE1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m */; };
|
||||
34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; };
|
||||
@ -584,6 +586,8 @@
|
||||
347850661FD9B789007B8332 /* AppSetup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppSetup.h; sourceTree = "<group>"; };
|
||||
347850671FD9B78A007B8332 /* NoopCallMessageHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoopCallMessageHandler.swift; sourceTree = "<group>"; };
|
||||
347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = "<group>"; };
|
||||
3478506F1FDAEB16007B8332 /* OWSUserProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSUserProfile.m; sourceTree = "<group>"; };
|
||||
347850701FDAEB16007B8332 /* OWSUserProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSUserProfile.h; sourceTree = "<group>"; };
|
||||
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceSleepManager.swift; sourceTree = "<group>"; };
|
||||
3495BC911F1426B800B478F5 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = translations/ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3497DBEA1ECE257500DB2605 /* OWSCountryMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCountryMetadata.h; sourceTree = "<group>"; };
|
||||
@ -1225,6 +1229,8 @@
|
||||
children = (
|
||||
346129B11FD1F7E800532771 /* OWSProfileManager.h */,
|
||||
346129B21FD1F7E800532771 /* OWSProfileManager.m */,
|
||||
347850701FDAEB16007B8332 /* OWSUserProfile.h */,
|
||||
3478506F1FDAEB16007B8332 /* OWSUserProfile.m */,
|
||||
346129B31FD1F7E800532771 /* ProfileFetcherJob.swift */,
|
||||
);
|
||||
path = profiles;
|
||||
@ -2041,6 +2047,7 @@
|
||||
3461295A1FD1D74C00532771 /* Environment.h in Headers */,
|
||||
34480B631FD0A98800BC14EF /* UIView+OWS.h in Headers */,
|
||||
451F8A4B1FD715E1005CB9DA /* OWSGroupAvatarBuilder.h in Headers */,
|
||||
347850721FDAEB17007B8332 /* OWSUserProfile.h in Headers */,
|
||||
451F8A371FD71179005CB9DA /* OWSViewController.h in Headers */,
|
||||
454A965D1FD602B1008D2A0E /* OWSAudioAttachmentPlayer.h in Headers */,
|
||||
451F8A3E1FD713D2005CB9DA /* ThreadViewHelper.h in Headers */,
|
||||
@ -2730,6 +2737,7 @@
|
||||
346129F71FD5F31400532771 /* OWS105AttachmentFilePaths.m in Sources */,
|
||||
45194F931FD7215C00333B2C /* OWSContactOffersInteraction.m in Sources */,
|
||||
450998681FD8C0FF00D89EB3 /* AttachmentSharing.m in Sources */,
|
||||
347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */,
|
||||
346129761FD1E0B500532771 /* WeakTimer.swift in Sources */,
|
||||
346129F81FD5F31400532771 /* OWS100RemoveTSRecipientsMigration.m in Sources */,
|
||||
45E547201FD755E700DFC09E /* AttachmentApprovalViewController.swift in Sources */,
|
||||
|
||||
@ -356,7 +356,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
DDLogWarn(@"%@ applicationDidBecomeActive.", self.logTag);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
83
SignalMessaging/profiles/OWSUserProfile.h
Normal file
83
SignalMessaging/profiles/OWSUserProfile.h
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalServiceKit/TSYapDatabaseObject.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSUserProfileCompletion)(void);
|
||||
|
||||
@class OWSAES256Key;
|
||||
|
||||
extern NSString *const kLocalProfileUniqueId;
|
||||
|
||||
// This class should be completely thread-safe.
|
||||
@interface OWSUserProfile : TSYapDatabaseObject
|
||||
|
||||
@property (atomic, readonly) NSString *recipientId;
|
||||
@property (atomic, readonly, nullable) OWSAES256Key *profileKey;
|
||||
@property (atomic, readonly, nullable) NSString *profileName;
|
||||
@property (atomic, readonly, nullable) NSString *avatarUrlPath;
|
||||
// This filename is relative to OWSProfileManager.profileAvatarsDirPath.
|
||||
@property (atomic, readonly, nullable) NSString *avatarFileName;
|
||||
|
||||
// This should reflect when either:
|
||||
//
|
||||
// * The last successful update finished.
|
||||
// * The current in-flight update began.
|
||||
@property (atomic, readonly, nullable) NSDate *lastUpdateDate;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
+ (OWSUserProfile *)getOrBuildUserProfileForRecipientId:(NSString *)recipientId
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection;
|
||||
|
||||
#pragma mark - Update With... Methods
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
profileKey:(OWSAES256Key *)profileKey
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
lastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
lastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithAvatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithAvatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)updateWithLastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
- (void)clearWithProfileKey:(OWSAES256Key *)profileKey
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
250
SignalMessaging/profiles/OWSUserProfile.m
Normal file
250
SignalMessaging/profiles/OWSUserProfile.m
Normal file
@ -0,0 +1,250 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSUserProfile.h"
|
||||
#import "NSString+OWS.h"
|
||||
#import <SignalServiceKit/Cryptography.h>
|
||||
#import <YapDatabase/YapDatabaseConnection.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
|
||||
|
||||
@interface OWSUserProfile ()
|
||||
|
||||
@property (atomic, nullable) OWSAES256Key *profileKey;
|
||||
@property (atomic, nullable) NSString *profileName;
|
||||
@property (atomic, nullable) NSString *avatarUrlPath;
|
||||
@property (atomic, nullable) NSString *avatarFileName;
|
||||
@property (atomic, nullable) NSDate *lastUpdateDate;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSUserProfile
|
||||
|
||||
+ (OWSUserProfile *)getOrBuildUserProfileForRecipientId:(NSString *)recipientId
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
{
|
||||
OWSAssert(recipientId.length > 0);
|
||||
|
||||
__block OWSUserProfile *userProfile;
|
||||
[dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
userProfile = [OWSUserProfile fetchObjectWithUniqueID:recipientId transaction:transaction];
|
||||
}];
|
||||
|
||||
if (!userProfile) {
|
||||
userProfile = [[OWSUserProfile alloc] initWithRecipientId:recipientId];
|
||||
|
||||
if ([recipientId isEqualToString:kLocalProfileUniqueId]) {
|
||||
[userProfile updateImmediatelyWithProfileKey:[OWSAES256Key generateRandomKey]
|
||||
dbConnection:dbConnection
|
||||
completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
OWSAssert(userProfile);
|
||||
|
||||
return userProfile;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRecipientId:(NSString *)recipientId
|
||||
{
|
||||
self = [super initWithUniqueId:recipientId];
|
||||
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
OWSAssert(recipientId.length > 0);
|
||||
_recipientId = recipientId;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Update With... Methods
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileName:[profileName ows_stripped]];
|
||||
[userProfile setAvatarUrlPath:avatarUrlPath];
|
||||
[userProfile setAvatarFileName:avatarFileName];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
lastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileName:[profileName ows_stripped]];
|
||||
[userProfile setAvatarUrlPath:avatarUrlPath];
|
||||
[userProfile setAvatarFileName:avatarFileName];
|
||||
[userProfile setLastUpdateDate:lastUpdateDate];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
lastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileName:[profileName ows_stripped]];
|
||||
[userProfile setAvatarUrlPath:avatarUrlPath];
|
||||
[userProfile setLastUpdateDate:lastUpdateDate];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithProfileName:(nullable NSString *)profileName
|
||||
profileKey:(OWSAES256Key *)profileKey
|
||||
avatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileName:[profileName ows_stripped]];
|
||||
[userProfile setProfileKey:profileKey];
|
||||
[userProfile setAvatarUrlPath:avatarUrlPath];
|
||||
[userProfile setAvatarFileName:avatarFileName];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithAvatarUrlPath:(nullable NSString *)avatarUrlPath
|
||||
avatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setAvatarUrlPath:avatarUrlPath];
|
||||
[userProfile setAvatarFileName:avatarFileName];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithAvatarFileName:(nullable NSString *)avatarFileName
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setAvatarFileName:avatarFileName];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateWithLastUpdateDate:(nullable NSDate *)lastUpdateDate
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion
|
||||
{
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setLastUpdateDate:lastUpdateDate];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)clearWithProfileKey:(OWSAES256Key *)profileKey
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
{
|
||||
OWSAssert(profileKey);
|
||||
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileKey:profileKey];
|
||||
[userProfile setProfileName:nil];
|
||||
[userProfile setAvatarUrlPath:nil];
|
||||
[userProfile setAvatarFileName:nil];
|
||||
[userProfile setLastUpdateDate:nil];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
- (void)updateImmediatelyWithProfileKey:(OWSAES256Key *)profileKey
|
||||
dbConnection:(YapDatabaseConnection *)dbConnection
|
||||
completion:(nullable OWSUserProfileCompletion)completion;
|
||||
{
|
||||
OWSAssert(profileKey);
|
||||
|
||||
self.profileKey = profileKey;
|
||||
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[self applyChangeToSelfAndLatestCopy:transaction
|
||||
changeBlock:^(OWSUserProfile *userProfile) {
|
||||
[userProfile setProfileKey:profileKey];
|
||||
}];
|
||||
}
|
||||
completionBlock:completion];
|
||||
}
|
||||
|
||||
#pragma mark - Database Connection Accessors
|
||||
|
||||
- (YapDatabaseConnection *)dbReadConnection
|
||||
{
|
||||
OWSFail(@"%@ UserProfile should always use OWSProfileManager's database connection.", self.logTag);
|
||||
|
||||
return TSYapDatabaseObject.dbReadConnection;
|
||||
}
|
||||
|
||||
+ (YapDatabaseConnection *)dbReadConnection
|
||||
{
|
||||
OWSFail(@"%@ UserProfile should always use OWSProfileManager's database connection.", self.logTag);
|
||||
|
||||
return TSYapDatabaseObject.dbReadConnection;
|
||||
}
|
||||
|
||||
- (YapDatabaseConnection *)dbReadWriteConnection
|
||||
{
|
||||
OWSFail(@"%@ UserProfile should always use OWSProfileManager's database connection.", self.logTag);
|
||||
|
||||
return TSYapDatabaseObject.dbReadWriteConnection;
|
||||
}
|
||||
|
||||
+ (YapDatabaseConnection *)dbReadWriteConnection
|
||||
{
|
||||
OWSFail(@"%@ UserProfile should always use OWSProfileManager's database connection.", self.logTag);
|
||||
|
||||
return TSYapDatabaseObject.dbReadWriteConnection;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Loading…
Reference in New Issue
Block a user