|
|
|
@ -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
|
|
|
|
|