| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -14,10 +14,51 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				NSString *const kOWSSoundsStorageNotificationCollection = @"kOWSSoundsStorageNotificationCollection";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlobalNotificationKey";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@interface OWSSystemSound : NSObject
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@property (nonatomic, readonly) SystemSoundID soundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@property (nonatomic, readonly) NSURL *soundURL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- (instancetype)init NS_UNAVAILABLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- (instancetype)initWithURL:(NSURL *)url NS_DESIGNATED_INITIALIZER;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@end
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@implementation OWSSystemSound
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- (instancetype)initWithURL:(NSURL *)url
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self = [super init];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!self) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return self;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DDLogDebug(@"%@ creating system sound for %@", self.logTag, url.lastPathComponent);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    _soundURL = url;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SystemSoundID newSoundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &newSoundID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSAssert(status == kAudioServicesNoError);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSAssert(newSoundID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    _soundID = newSoundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return self;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- (void)dealloc
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DDLogDebug(@"%@ in dealloc disposing sound: %@", self.logTag, _soundURL.lastPathComponent);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OSStatus status = AudioServicesDisposeSystemSoundID(_soundID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSAssert(status == kAudioServicesNoError);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@end
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@interface OWSSounds ()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@property (nonatomic, readonly) AnyLRUCache *cachedSoundIDs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@property (nonatomic, readonly) AnyLRUCache *cachedSystemSounds;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@end
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -55,7 +96,7 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    _dbConnection = primaryStorage.newDatabaseConnection;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Don't store too many sounds in memory. Most users will only use 1 or 2 sounds anyway.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    _cachedSoundIDs = [[AnyLRUCache alloc] initWithMaxSize:3];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    _cachedSystemSounds = [[AnyLRUCache alloc] initWithMaxSize:3];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSSingletonAssert();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -220,24 +261,18 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- (SystemSoundID)systemSoundIDForSound:(OWSSound)sound quiet:(BOOL)quiet
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    NSString *cacheKey = [NSString stringWithFormat:@"%lu:%d", (unsigned long)sound, quiet];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    NSNumber *_Nullable cachedSoundId = (NSNumber * _Nullable)[self.cachedSoundIDs getWithKey:cacheKey];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSSystemSound *_Nullable cachedSound = (OWSSystemSound *)[self.cachedSystemSounds getWithKey:cacheKey];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (cachedSoundId) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        OWSAssert([cachedSoundId isKindOfClass:[NSNumber class]]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return (SystemSoundID)cachedSoundId.intValue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (cachedSound) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        OWSAssert([cachedSound isKindOfClass:[OWSSystemSound class]]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return cachedSound.soundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    NSURL *soundURL = [self.class soundURLForSound:sound quiet:quiet];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSSystemSound *newSound = [[OWSSystemSound alloc] initWithURL:soundURL];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    [self.cachedSystemSounds setWithKey:cacheKey value:newSound];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DDLogVerbose(@"%@ creating system sound for %@", self.logTag, soundURL.lastPathComponent);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SystemSoundID newSoundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(soundURL), &newSoundID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSAssert(status == 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    OWSAssert(newSoundID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    [self.cachedSoundIDs setWithKey:cacheKey value:@(newSoundID)];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return newSoundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return newSound.soundID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#pragma mark - Notifications
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |