Clean up custom sound IDs
This commit is contained in:
parent
4f0c2c3deb
commit
59066a233d
@ -772,6 +772,7 @@
|
||||
508C72242C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508C72232C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift */; };
|
||||
508F0346296F72F4001D88D0 /* CustomCellBackgroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508F0345296F72F4001D88D0 /* CustomCellBackgroundColor.swift */; };
|
||||
508F05A52FA28308004B96E5 /* CGDataProvider+SSK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508F05A42FA28308004B96E5 /* CGDataProvider+SSK.swift */; };
|
||||
508F05A72FA294DD004B96E5 /* SoundsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508F05A62FA294DD004B96E5 /* SoundsTest.swift */; };
|
||||
509085B82C498C3F00409B85 /* HTMLMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CABC289453B200548EEE /* HTMLMetadata.swift */; };
|
||||
509085BA2C498C4400409B85 /* HTMLMetadataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F94261D4289B1B5400460798 /* HTMLMetadataTests.swift */; };
|
||||
509085BC2C498D3600409B85 /* LinkPreviewFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 509085BB2C498D3500409B85 /* LinkPreviewFetcher.swift */; };
|
||||
@ -5052,6 +5053,7 @@
|
||||
508C72232C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSOutgoingResendResponseTest.swift; sourceTree = "<group>"; };
|
||||
508F0345296F72F4001D88D0 /* CustomCellBackgroundColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCellBackgroundColor.swift; sourceTree = "<group>"; };
|
||||
508F05A42FA28308004B96E5 /* CGDataProvider+SSK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGDataProvider+SSK.swift"; sourceTree = "<group>"; };
|
||||
508F05A62FA294DD004B96E5 /* SoundsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundsTest.swift; sourceTree = "<group>"; };
|
||||
509085BB2C498D3500409B85 /* LinkPreviewFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewFetcher.swift; sourceTree = "<group>"; };
|
||||
509085BD2C49C29400409B85 /* PaddingBucket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingBucket.swift; sourceTree = "<group>"; };
|
||||
509085BF2C49C2A500409B85 /* PaddingBucketTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingBucketTest.swift; sourceTree = "<group>"; };
|
||||
@ -14381,6 +14383,7 @@
|
||||
F94261F0289B1B5400460798 /* RefineryTest.swift */,
|
||||
F94261EC289B1B5400460798 /* RemoteConfigManagerTests.swift */,
|
||||
502346782DB03DEB0029DB97 /* SetDequeTest.swift */,
|
||||
508F05A62FA294DD004B96E5 /* SoundsTest.swift */,
|
||||
F9613CDD2981F15700894B55 /* SqliteUtilTest.swift */,
|
||||
C14EC1A82BAA4B5F00A4D064 /* StreamTransformTests.swift */,
|
||||
7205701F2C8E860300826421 /* StringExtensionTests.swift */,
|
||||
@ -20324,6 +20327,7 @@
|
||||
F94262A0289B1B5600460798 /* SMKSecretSessionCipherTest.swift in Sources */,
|
||||
F9426296289B1B5600460798 /* SMKTestUtils.swift in Sources */,
|
||||
F9426298289B1B5600460798 /* SMKUDAccessKeyTest.swift in Sources */,
|
||||
508F05A72FA294DD004B96E5 /* SoundsTest.swift in Sources */,
|
||||
F9A392B9297F2ED5007964E5 /* SpamReportingTokenRecordTest.swift in Sources */,
|
||||
F9427EAE297F1EE3008EF0AC /* SpamReportingTokenTest.swift in Sources */,
|
||||
6664B9AB2A314EBD008EF74B /* SpoilerRevealStateTests.swift in Sources */,
|
||||
|
||||
@ -17,10 +17,10 @@ public enum Sound: Equatable {
|
||||
|
||||
public extension Sound {
|
||||
|
||||
var id: UInt {
|
||||
var id: UInt64 {
|
||||
switch self {
|
||||
case .standard(let standardSound):
|
||||
return standardSound.rawValue
|
||||
return UInt64(safeCast: standardSound.rawValue)
|
||||
case .custom(let customSound):
|
||||
return customSound.id
|
||||
}
|
||||
@ -68,7 +68,8 @@ public extension Sound {
|
||||
}
|
||||
}
|
||||
|
||||
public enum StandardSound: UInt {
|
||||
// Limited to 16 bits to avoid colliding with CustomSound.id
|
||||
public enum StandardSound: UInt16 {
|
||||
case `default` = 0
|
||||
|
||||
// Notification Sounds
|
||||
@ -207,7 +208,7 @@ public extension StandardSound {
|
||||
|
||||
public struct CustomSound {
|
||||
|
||||
let id: UInt
|
||||
let id: UInt64
|
||||
let filename: String
|
||||
|
||||
init(filename: String) {
|
||||
@ -246,14 +247,12 @@ public struct CustomSound {
|
||||
|
||||
// MARK: -
|
||||
|
||||
private static let customSoundShift: UInt = 16
|
||||
// To avoid colliding with StandardSound.rawValue
|
||||
private static let customSoundShift: Int = 16
|
||||
|
||||
private static func idFromFilename(_ filename: String) -> UInt {
|
||||
let filenameData = Data(filename.utf8)
|
||||
let hashValue = SHA256.hash(data: filenameData).withUnsafeBytes {
|
||||
$0.loadUnaligned(as: UInt.self)
|
||||
}
|
||||
return hashValue << customSoundShift
|
||||
static func idFromFilename(_ filename: String) -> UInt64 {
|
||||
let hashValue = SHA256.hash(data: Data(filename.utf8))
|
||||
return UInt64(littleEndianData: Data(hashValue))! << customSoundShift
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +331,7 @@ public class Sounds {
|
||||
}
|
||||
|
||||
public static func systemSoundIDForSound(_ sound: Sound, quiet: Bool) -> SystemSoundID? {
|
||||
let cacheKey = String(format: "%lu:%d", sound.id, quiet)
|
||||
let cacheKey = "\(sound.id):\(quiet)"
|
||||
if let cachedSound = cachedSystemSounds.get(key: cacheKey) {
|
||||
return cachedSound.id
|
||||
}
|
||||
@ -374,8 +373,11 @@ public class Sounds {
|
||||
|
||||
public static var defaultNotificationSound: Sound { .standard(.note) }
|
||||
|
||||
private static func soundForId(_ soundId: UInt) -> Sound {
|
||||
if let standardSound = StandardSound(rawValue: soundId) {
|
||||
private static func soundForId(_ soundId: UInt64) -> Sound {
|
||||
if
|
||||
let soundId = UInt16(exactly: soundId),
|
||||
let standardSound = StandardSound(rawValue: soundId)
|
||||
{
|
||||
return .standard(standardSound)
|
||||
}
|
||||
if let customSound = CustomSound.all.first(where: { $0.id == soundId }) {
|
||||
@ -386,7 +388,7 @@ public class Sounds {
|
||||
|
||||
public static var globalNotificationSound: Sound {
|
||||
let soundId = SSKEnvironment.shared.databaseStorageRef.read { transaction in
|
||||
return keyValueStore.getUInt(soundsStorageGlobalNotificationKey, transaction: transaction)
|
||||
return keyValueStore.getUInt64(soundsStorageGlobalNotificationKey, transaction: transaction)
|
||||
}
|
||||
guard let soundId else { return defaultNotificationSound }
|
||||
return soundForId(soundId)
|
||||
@ -432,12 +434,12 @@ public class Sounds {
|
||||
// user hasn't authenticated after power-cycling their device.
|
||||
OWSFileSystem.protectFileOrFolder(atPath: defaultSoundUrl.path, fileProtectionType: .none)
|
||||
|
||||
keyValueStore.setUInt(sound.id, key: soundsStorageGlobalNotificationKey, transaction: transaction)
|
||||
keyValueStore.setUInt64(sound.id, key: soundsStorageGlobalNotificationKey, transaction: transaction)
|
||||
}
|
||||
|
||||
public static func notificationSoundWithSneakyTransaction(forThreadUniqueId threadUniqueId: String) -> Sound {
|
||||
let soundId = SSKEnvironment.shared.databaseStorageRef.read { transaction in
|
||||
return keyValueStore.getUInt(threadUniqueId, transaction: transaction)
|
||||
return keyValueStore.getUInt64(threadUniqueId, transaction: transaction)
|
||||
}
|
||||
guard let soundId else { return globalNotificationSound }
|
||||
return soundForId(soundId)
|
||||
@ -445,7 +447,7 @@ public class Sounds {
|
||||
|
||||
public static func setNotificationSound(_ sound: Sound, forThread thread: TSThread) {
|
||||
SSKEnvironment.shared.databaseStorageRef.write { transaction in
|
||||
keyValueStore.setUInt(sound.id, key: thread.uniqueId, transaction: transaction)
|
||||
keyValueStore.setUInt64(sound.id, key: thread.uniqueId, transaction: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +498,7 @@ public class Sounds {
|
||||
|
||||
let allInUseSoundIds = SSKEnvironment.shared.databaseStorageRef.read { transaction in
|
||||
return Set(keyValueStore.allKeys(transaction: transaction).compactMap {
|
||||
return keyValueStore.getUInt($0, transaction: transaction)
|
||||
return keyValueStore.getUInt64($0, transaction: transaction)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
18
SignalServiceKit/tests/Util/SoundsTest.swift
Normal file
18
SignalServiceKit/tests/Util/SoundsTest.swift
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Copyright 2026 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import SignalServiceKit
|
||||
|
||||
struct SoundsTest {
|
||||
@Test(arguments: [
|
||||
("Hello.m4a", 7562547131314274304),
|
||||
("Goodbye.mp4", 10601446312307589120),
|
||||
])
|
||||
func testCustomSoundId(testCase: (filename: String, id: UInt64)) {
|
||||
#expect(CustomSound.idFromFilename(testCase.filename) == testCase.id)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user