Merge branch 'charlesmchen/customNotificationSounds2'

This commit is contained in:
Matthew Chen 2018-02-23 12:54:24 -05:00
commit f7935bc363
64 changed files with 1102 additions and 106 deletions

View File

@ -8,6 +8,48 @@
/* Begin PBXBuildFile section */
2AE2882E4C2B96BFFF9EE27C /* Pods_SignalShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F94C85CB0B235DA37F68ED0 /* Pods_SignalShareExtension.framework */; };
34074F5B203D093B004596AE /* OWSSoundSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */; };
34074F61203D0CBE004596AE /* OWSSounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F5F203D0CBD004596AE /* OWSSounds.m */; };
34074F62203D0CBE004596AE /* OWSSounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 34074F60203D0CBE004596AE /* OWSSounds.h */; settings = {ATTRIBUTES = (Public, ); }; };
34074FEE203E5436004596AE /* aurora.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FC6203E5435004596AE /* aurora.m4r */; };
34074FEF203E5436004596AE /* bamboo.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FC7203E5435004596AE /* bamboo.m4r */; };
34074FF0203E5436004596AE /* chord.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FC8203E5435004596AE /* chord.m4r */; };
34074FF1203E5436004596AE /* circles.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FC9203E5435004596AE /* circles.m4r */; };
34074FF2203E5436004596AE /* complete.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCA203E5435004596AE /* complete.m4r */; };
34074FF3203E5436004596AE /* hello.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCB203E5435004596AE /* hello.m4r */; };
34074FF4203E5436004596AE /* input.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCC203E5435004596AE /* input.m4r */; };
34074FF5203E5436004596AE /* keys.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCD203E5435004596AE /* keys.m4r */; };
34074FF6203E5436004596AE /* note.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCE203E5435004596AE /* note.m4r */; };
34074FF7203E5436004596AE /* popcorn.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FCF203E5435004596AE /* popcorn.m4r */; };
34074FF8203E5436004596AE /* pulse.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD0203E5435004596AE /* pulse.m4r */; };
34074FF9203E5436004596AE /* synth.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD1203E5435004596AE /* synth.m4r */; };
34074FFA203E5436004596AE /* Apex.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD3203E5436004596AE /* Apex.m4r */; };
34074FFB203E5436004596AE /* Beacon.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD4203E5436004596AE /* Beacon.m4r */; };
34074FFC203E5436004596AE /* Bulletin.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD5203E5436004596AE /* Bulletin.m4r */; };
34074FFD203E5436004596AE /* By The Seaside.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD6203E5436004596AE /* By The Seaside.m4r */; };
34074FFE203E5436004596AE /* Chimes.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD7203E5436004596AE /* Chimes.m4r */; };
34074FFF203E5436004596AE /* Circuit.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD8203E5436004596AE /* Circuit.m4r */; };
34075000203E5436004596AE /* Constellation.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FD9203E5436004596AE /* Constellation.m4r */; };
34075001203E5436004596AE /* Cosmic.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDA203E5436004596AE /* Cosmic.m4r */; };
34075002203E5436004596AE /* Crystals.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDB203E5436004596AE /* Crystals.m4r */; };
34075003203E5436004596AE /* Hillside.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDC203E5436004596AE /* Hillside.m4r */; };
34075004203E5436004596AE /* Illuminate.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDD203E5436004596AE /* Illuminate.m4r */; };
34075005203E5436004596AE /* Night Owl.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDE203E5436004596AE /* Night Owl.m4r */; };
34075006203E5436004596AE /* Opening.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FDF203E5436004596AE /* Opening.m4r */; };
34075007203E5436004596AE /* Playtime.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE0203E5436004596AE /* Playtime.m4r */; };
34075008203E5436004596AE /* Presto.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE1203E5436004596AE /* Presto.m4r */; };
34075009203E5436004596AE /* Radar.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE2203E5436004596AE /* Radar.m4r */; };
3407500A203E5436004596AE /* Radiate.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE3203E5436004596AE /* Radiate.m4r */; };
3407500B203E5436004596AE /* Ripples.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE4203E5436004596AE /* Ripples.m4r */; };
3407500C203E5436004596AE /* Sencha.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE5203E5436004596AE /* Sencha.m4r */; };
3407500D203E5436004596AE /* Signal.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE6203E5436004596AE /* Signal.m4r */; };
3407500E203E5436004596AE /* Silk.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE7203E5436004596AE /* Silk.m4r */; };
3407500F203E5436004596AE /* Slow Rise.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE8203E5436004596AE /* Slow Rise.m4r */; };
34075010203E5436004596AE /* Stargaze.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FE9203E5436004596AE /* Stargaze.m4r */; };
34075011203E5436004596AE /* Summit.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FEA203E5436004596AE /* Summit.m4r */; };
34075012203E5436004596AE /* Twinkle.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FEB203E5436004596AE /* Twinkle.m4r */; };
34075013203E5436004596AE /* Uplift.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FEC203E5436004596AE /* Uplift.m4r */; };
34075014203E5436004596AE /* Waves.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FED203E5436004596AE /* Waves.m4r */; };
340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */; };
340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */; };
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; };
@ -166,6 +208,10 @@
34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; };
34CCAF3B1F0C2748004084F4 /* OWSAddToContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */; };
34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CE88E61F2FB9A10098030F /* ProfileViewController.m */; };
34CF0787203E6B78005C4D61 /* busy_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */; };
34CF0788203E6B78005C4D61 /* ringback_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0784203E6B77005C4D61 /* ringback_tone_ansi.caf */; };
34CF0789203E6B78005C4D61 /* ringback_tone_cept.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0785203E6B77005C4D61 /* ringback_tone_cept.caf */; };
34CF078A203E6B78005C4D61 /* end_call_tone_cept.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0786203E6B78005C4D61 /* end_call_tone_cept.caf */; };
34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D1F04F1F7D45A60066283D /* GifPickerCell.swift */; };
34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D1F0511F7E8EA30066283D /* GiphyDownloader.swift */; };
34D1F0821F8678AA0066283D /* ConversationHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D1F0661F8678AA0066283D /* ConversationHeaderView.m */; };
@ -349,7 +395,6 @@
B10C9B621A7049EC00ECA2BF /* play_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */; };
B609597C1C2C0FC6004E8797 /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = B609597B1C2C0FC6004E8797 /* iRate.m */; };
B60EDE041A05A01700D73516 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B60EDE031A05A01700D73516 /* AudioToolbox.framework */; };
B625CD561ABB589C00E8B23C /* NewMessage.aifc in Resources */ = {isa = PBXBuildFile; fileRef = B625CD551ABB589C00E8B23C /* NewMessage.aifc */; };
B633C5861A1D190B0059AC12 /* call@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5041A1D190B0059AC12 /* call@2x.png */; };
B633C58D1A1D190B0059AC12 /* contact_default_feed.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50B1A1D190B0059AC12 /* contact_default_feed.png */; };
B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51B1A1D190B0059AC12 /* endcall@2x.png */; };
@ -392,11 +437,6 @@
D24B5BD5169F568C00681372 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D24B5BD4169F568C00681372 /* AudioToolbox.framework */; };
D2AEACDC16C426DA00C364C0 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */; };
E1368CBE18A1C36B00109378 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; };
E1370BE018A0686600826894 /* busy.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = E18AB40718A05754001A532A /* busy.mp3 */; };
E1370BE218A0686C00826894 /* failure.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = E18AB40918A05754001A532A /* failure.mp3 */; };
E1370BE418A0686C00826894 /* outring.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = E18AB40B18A05754001A532A /* outring.mp3 */; };
E1370BE518A0686C00826894 /* r.caf in Resources */ = {isa = PBXBuildFile; fileRef = E18AB40C18A05754001A532A /* r.caf */; };
E1370BE618A0686C00826894 /* sonarping.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = E18AB40D18A05754001A532A /* sonarping.mp3 */; };
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */ = {isa = PBXBuildFile; fileRef = EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */; };
FC3BD9881A30A790005B96BB /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC3BD9871A30A790005B96BB /* Social.framework */; };
FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF371A3393DD00B47253 /* error_white@2x.png */; };
@ -478,6 +518,49 @@
3400C7951EAF99F4008A8584 /* SelectThreadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectThreadViewController.m; sourceTree = "<group>"; };
3400C7971EAFB772008A8584 /* ThreadViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadViewHelper.h; sourceTree = "<group>"; };
3400C7981EAFB772008A8584 /* ThreadViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadViewHelper.m; sourceTree = "<group>"; };
34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSoundSettingsViewController.m; sourceTree = "<group>"; };
34074F5A203D093B004596AE /* OWSSoundSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSoundSettingsViewController.h; sourceTree = "<group>"; };
34074F5F203D0CBD004596AE /* OWSSounds.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSounds.m; sourceTree = "<group>"; };
34074F60203D0CBE004596AE /* OWSSounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSounds.h; sourceTree = "<group>"; };
34074FC6203E5435004596AE /* aurora.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = aurora.m4r; sourceTree = "<group>"; };
34074FC7203E5435004596AE /* bamboo.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = bamboo.m4r; sourceTree = "<group>"; };
34074FC8203E5435004596AE /* chord.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = chord.m4r; sourceTree = "<group>"; };
34074FC9203E5435004596AE /* circles.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = circles.m4r; sourceTree = "<group>"; };
34074FCA203E5435004596AE /* complete.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = complete.m4r; sourceTree = "<group>"; };
34074FCB203E5435004596AE /* hello.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = hello.m4r; sourceTree = "<group>"; };
34074FCC203E5435004596AE /* input.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = input.m4r; sourceTree = "<group>"; };
34074FCD203E5435004596AE /* keys.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = keys.m4r; sourceTree = "<group>"; };
34074FCE203E5435004596AE /* note.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = note.m4r; sourceTree = "<group>"; };
34074FCF203E5435004596AE /* popcorn.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = popcorn.m4r; sourceTree = "<group>"; };
34074FD0203E5435004596AE /* pulse.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = pulse.m4r; sourceTree = "<group>"; };
34074FD1203E5435004596AE /* synth.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = synth.m4r; sourceTree = "<group>"; };
34074FD3203E5436004596AE /* Apex.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Apex.m4r; sourceTree = "<group>"; };
34074FD4203E5436004596AE /* Beacon.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Beacon.m4r; sourceTree = "<group>"; };
34074FD5203E5436004596AE /* Bulletin.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Bulletin.m4r; sourceTree = "<group>"; };
34074FD6203E5436004596AE /* By The Seaside.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = "By The Seaside.m4r"; sourceTree = "<group>"; };
34074FD7203E5436004596AE /* Chimes.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Chimes.m4r; sourceTree = "<group>"; };
34074FD8203E5436004596AE /* Circuit.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Circuit.m4r; sourceTree = "<group>"; };
34074FD9203E5436004596AE /* Constellation.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Constellation.m4r; sourceTree = "<group>"; };
34074FDA203E5436004596AE /* Cosmic.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Cosmic.m4r; sourceTree = "<group>"; };
34074FDB203E5436004596AE /* Crystals.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Crystals.m4r; sourceTree = "<group>"; };
34074FDC203E5436004596AE /* Hillside.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Hillside.m4r; sourceTree = "<group>"; };
34074FDD203E5436004596AE /* Illuminate.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Illuminate.m4r; sourceTree = "<group>"; };
34074FDE203E5436004596AE /* Night Owl.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Night Owl.m4r"; sourceTree = "<group>"; };
34074FDF203E5436004596AE /* Opening.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Opening.m4r; sourceTree = "<group>"; };
34074FE0203E5436004596AE /* Playtime.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Playtime.m4r; sourceTree = "<group>"; };
34074FE1203E5436004596AE /* Presto.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Presto.m4r; sourceTree = "<group>"; };
34074FE2203E5436004596AE /* Radar.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Radar.m4r; sourceTree = "<group>"; };
34074FE3203E5436004596AE /* Radiate.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Radiate.m4r; sourceTree = "<group>"; };
34074FE4203E5436004596AE /* Ripples.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Ripples.m4r; sourceTree = "<group>"; };
34074FE5203E5436004596AE /* Sencha.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Sencha.m4r; sourceTree = "<group>"; };
34074FE6203E5436004596AE /* Signal.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Signal.m4r; sourceTree = "<group>"; };
34074FE7203E5436004596AE /* Silk.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Silk.m4r; sourceTree = "<group>"; };
34074FE8203E5436004596AE /* Slow Rise.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Slow Rise.m4r"; sourceTree = "<group>"; };
34074FE9203E5436004596AE /* Stargaze.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Stargaze.m4r; sourceTree = "<group>"; };
34074FEA203E5436004596AE /* Summit.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Summit.m4r; sourceTree = "<group>"; };
34074FEB203E5436004596AE /* Twinkle.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Twinkle.m4r; sourceTree = "<group>"; };
34074FEC203E5436004596AE /* Uplift.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Uplift.m4r; sourceTree = "<group>"; };
34074FED203E5436004596AE /* Waves.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; path = Waves.m4r; sourceTree = "<group>"; };
340B02B61F9FD31800F9CFEC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = translations/he.lproj/Localizable.strings; sourceTree = "<group>"; };
340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationViewItemTest.m; sourceTree = "<group>"; };
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewHelper.h; sourceTree = "<group>"; };
@ -696,6 +779,10 @@
34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSAddToContactViewController.m; sourceTree = "<group>"; };
34CE88E51F2FB9A10098030F /* ProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileViewController.h; sourceTree = "<group>"; };
34CE88E61F2FB9A10098030F /* ProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileViewController.m; sourceTree = "<group>"; };
34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = busy_tone_ansi.caf; path = Signal/AudioFiles/busy_tone_ansi.caf; sourceTree = SOURCE_ROOT; };
34CF0784203E6B77005C4D61 /* ringback_tone_ansi.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = ringback_tone_ansi.caf; path = Signal/AudioFiles/ringback_tone_ansi.caf; sourceTree = SOURCE_ROOT; };
34CF0785203E6B77005C4D61 /* ringback_tone_cept.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = ringback_tone_cept.caf; path = Signal/AudioFiles/ringback_tone_cept.caf; sourceTree = SOURCE_ROOT; };
34CF0786203E6B78005C4D61 /* end_call_tone_cept.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = end_call_tone_cept.caf; path = Signal/AudioFiles/end_call_tone_cept.caf; sourceTree = SOURCE_ROOT; };
34D1F04F1F7D45A60066283D /* GifPickerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GifPickerCell.swift; sourceTree = "<group>"; };
34D1F0511F7E8EA30066283D /* GiphyDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GiphyDownloader.swift; sourceTree = "<group>"; };
34D1F0651F8678AA0066283D /* ConversationHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationHeaderView.h; sourceTree = "<group>"; };
@ -908,7 +995,6 @@
B609597A1C2C0FC6004E8797 /* iRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iRate.h; path = Libraries/iRate/iRate.h; sourceTree = SOURCE_ROOT; };
B609597B1C2C0FC6004E8797 /* iRate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iRate.m; path = Libraries/iRate/iRate.m; sourceTree = SOURCE_ROOT; };
B60EDE031A05A01700D73516 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
B625CD551ABB589C00E8B23C /* NewMessage.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = NewMessage.aifc; sourceTree = "<group>"; };
B633C5041A1D190B0059AC12 /* call@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call@2x.png"; sourceTree = "<group>"; };
B633C50B1A1D190B0059AC12 /* contact_default_feed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_default_feed.png; sourceTree = "<group>"; };
B633C51B1A1D190B0059AC12 /* endcall@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "endcall@2x.png"; sourceTree = "<group>"; };
@ -987,11 +1073,6 @@
D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
DE2DD605305BC6EFAD731723 /* Pods-Signal.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Signal.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Signal/Pods-Signal.debug.xcconfig"; sourceTree = "<group>"; };
DF728B4B438716EAF95CEC18 /* Pods-Signal.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Signal.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-Signal/Pods-Signal.app store release.xcconfig"; sourceTree = "<group>"; };
E18AB40718A05754001A532A /* busy.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = busy.mp3; sourceTree = "<group>"; };
E18AB40918A05754001A532A /* failure.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = failure.mp3; sourceTree = "<group>"; };
E18AB40B18A05754001A532A /* outring.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = outring.mp3; sourceTree = "<group>"; };
E18AB40C18A05754001A532A /* r.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = r.caf; sourceTree = "<group>"; };
E18AB40D18A05754001A532A /* sonarping.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = sonarping.mp3; sourceTree = "<group>"; };
E1A0AD8B16E13FDD0071E604 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
E85DB184824BA9DC302EC8B3 /* Pods-SignalTests.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.app store release.xcconfig"; sourceTree = "<group>"; };
EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Permissions.h"; path = "util/UIViewController+Permissions.h"; sourceTree = "<group>"; };
@ -1086,6 +1167,74 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
34074F54203D0722004596AE /* Sounds */ = {
isa = PBXGroup;
children = (
34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */,
34CF0786203E6B78005C4D61 /* end_call_tone_cept.caf */,
34074FC5203E5435004596AE /* messageReceivedSounds */,
34CF0784203E6B77005C4D61 /* ringback_tone_ansi.caf */,
34CF0785203E6B77005C4D61 /* ringback_tone_cept.caf */,
34074FD2203E5436004596AE /* ringtoneSounds */,
);
path = Sounds;
sourceTree = "<group>";
};
34074FC5203E5435004596AE /* messageReceivedSounds */ = {
isa = PBXGroup;
children = (
34074FC6203E5435004596AE /* aurora.m4r */,
34074FC7203E5435004596AE /* bamboo.m4r */,
34074FC8203E5435004596AE /* chord.m4r */,
34074FC9203E5435004596AE /* circles.m4r */,
34074FCA203E5435004596AE /* complete.m4r */,
34074FCB203E5435004596AE /* hello.m4r */,
34074FCC203E5435004596AE /* input.m4r */,
34074FCD203E5435004596AE /* keys.m4r */,
34074FCE203E5435004596AE /* note.m4r */,
34074FCF203E5435004596AE /* popcorn.m4r */,
34074FD0203E5435004596AE /* pulse.m4r */,
34074FD1203E5435004596AE /* synth.m4r */,
);
name = messageReceivedSounds;
path = Signal/AudioFiles/messageReceivedSounds;
sourceTree = SOURCE_ROOT;
};
34074FD2203E5436004596AE /* ringtoneSounds */ = {
isa = PBXGroup;
children = (
34074FD3203E5436004596AE /* Apex.m4r */,
34074FD4203E5436004596AE /* Beacon.m4r */,
34074FD5203E5436004596AE /* Bulletin.m4r */,
34074FD6203E5436004596AE /* By The Seaside.m4r */,
34074FD7203E5436004596AE /* Chimes.m4r */,
34074FD8203E5436004596AE /* Circuit.m4r */,
34074FD9203E5436004596AE /* Constellation.m4r */,
34074FDA203E5436004596AE /* Cosmic.m4r */,
34074FDB203E5436004596AE /* Crystals.m4r */,
34074FDC203E5436004596AE /* Hillside.m4r */,
34074FDD203E5436004596AE /* Illuminate.m4r */,
34074FDE203E5436004596AE /* Night Owl.m4r */,
34074FDF203E5436004596AE /* Opening.m4r */,
34074FE0203E5436004596AE /* Playtime.m4r */,
34074FE1203E5436004596AE /* Presto.m4r */,
34074FE2203E5436004596AE /* Radar.m4r */,
34074FE3203E5436004596AE /* Radiate.m4r */,
34074FE4203E5436004596AE /* Ripples.m4r */,
34074FE5203E5436004596AE /* Sencha.m4r */,
34074FE6203E5436004596AE /* Signal.m4r */,
34074FE7203E5436004596AE /* Silk.m4r */,
34074FE8203E5436004596AE /* Slow Rise.m4r */,
34074FE9203E5436004596AE /* Stargaze.m4r */,
34074FEA203E5436004596AE /* Summit.m4r */,
34074FEB203E5436004596AE /* Twinkle.m4r */,
34074FEC203E5436004596AE /* Uplift.m4r */,
34074FED203E5436004596AE /* Waves.m4r */,
);
name = ringtoneSounds;
path = Signal/AudioFiles/ringtoneSounds;
sourceTree = SOURCE_ROOT;
};
34330A581E7875FB00DF2FB9 /* Fonts */ = {
isa = PBXGroup;
children = (
@ -1203,6 +1352,8 @@
347850671FD9B78A007B8332 /* NoopCallMessageHandler.swift */,
347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */,
45F170AB1E2F0351003FC1F2 /* OWSAudioSession.swift */,
34074F60203D0CBE004596AE /* OWSSounds.h */,
34074F5F203D0CBD004596AE /* OWSSounds.m */,
346129561FD1D74B00532771 /* Release.h */,
346129571FD1D74B00532771 /* Release.m */,
346129581FD1D74B00532771 /* SignalKeyingStorage.h */,
@ -1371,6 +1522,8 @@
34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */,
34B3F8621E8DF1700035BE1A /* OWSQRCodeScanningViewController.h */,
34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */,
34074F5A203D093B004596AE /* OWSSoundSettingsViewController.h */,
34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */,
34B3F8641E8DF1700035BE1A /* PrivacySettingsTableViewController.h */,
34B3F8651E8DF1700035BE1A /* PrivacySettingsTableViewController.m */,
34CE88E51F2FB9A10098030F /* ProfileViewController.h */,
@ -1992,14 +2145,15 @@
D221A093169C9E5E00537ABF /* Signal */ = {
isa = PBXGroup;
children = (
B657DDC91911A40500F45B0C /* Signal.entitlements */,
34330A581E7875FB00DF2FB9 /* Fonts */,
B633C4FD1A1D190B0059AC12 /* Images */,
B67EBF5C19194AC60084CCFD /* Settings.bundle */,
76EB03C118170B33006006FC /* src */,
B660F66C1C29867F00687D6E /* test */,
D221A094169C9E5E00537ABF /* Supporting Files */,
B66DBF4919D5BBC8006EA940 /* Images.xcassets */,
B67EBF5C19194AC60084CCFD /* Settings.bundle */,
B657DDC91911A40500F45B0C /* Signal.entitlements */,
34074F54203D0722004596AE /* Sounds */,
76EB03C118170B33006006FC /* src */,
D221A094169C9E5E00537ABF /* Supporting Files */,
B660F66C1C29867F00687D6E /* test */,
);
path = Signal;
sourceTree = "<group>";
@ -2008,7 +2162,6 @@
isa = PBXGroup;
children = (
B6B6C3C419193F5B00C0B76B /* Translations */,
E18AB40618A05754001A532A /* AudioFiles */,
D221A099169C9E5E00537ABF /* main.m */,
D221A095169C9E5E00537ABF /* Signal-Info.plist */,
D221A09B169C9E5E00537ABF /* Signal-Prefix.pch */,
@ -2016,19 +2169,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
E18AB40618A05754001A532A /* AudioFiles */ = {
isa = PBXGroup;
children = (
B625CD551ABB589C00E8B23C /* NewMessage.aifc */,
E18AB40718A05754001A532A /* busy.mp3 */,
E18AB40918A05754001A532A /* failure.mp3 */,
E18AB40B18A05754001A532A /* outring.mp3 */,
E18AB40C18A05754001A532A /* r.caf */,
E18AB40D18A05754001A532A /* sonarping.mp3 */,
);
path = AudioFiles;
sourceTree = "<group>";
};
FCFA64B11A24F29E0007FB87 /* UI Categories */ = {
isa = PBXGroup;
children = (
@ -2103,6 +2243,7 @@
45194F901FD7200000333B2C /* ThreadUtil.h in Headers */,
346129CC1FD2072E00532771 /* NSAttributedString+OWS.h in Headers */,
346129FD1FD5F31400532771 /* OWS102MoveLoggingPreferenceToUserDefaults.h in Headers */,
34074F62203D0CBE004596AE /* OWSSounds.h in Headers */,
344F2499200FD03300CFB4F4 /* SharingThreadPickerViewController.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -2368,42 +2509,79 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
34CF078A203E6B78005C4D61 /* end_call_tone_cept.caf in Resources */,
AD83FF3F1A73426500B5C81A /* audio_pause_button_blue.png in Resources */,
3407500C203E5436004596AE /* Sencha.m4r in Resources */,
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */,
A5509ECA1A69AB8B00ABA4BC /* Main.storyboard in Resources */,
AD83FF421A73426500B5C81A /* audio_play_button.png in Resources */,
34074FEF203E5436004596AE /* bamboo.m4r in Resources */,
34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */,
B633C5C41A1D190B0059AC12 /* mute_on@2x.png in Resources */,
B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */,
34075008203E5436004596AE /* Presto.m4r in Resources */,
34074FF1203E5436004596AE /* circles.m4r in Resources */,
AD83FF441A73426500B5C81A /* audio_pause_button.png in Resources */,
34075005203E5436004596AE /* Night Owl.m4r in Resources */,
B6F509971AA53F760068F56A /* Localizable.strings in Resources */,
B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */,
FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */,
34075003203E5436004596AE /* Hillside.m4r in Resources */,
34074FFA203E5436004596AE /* Apex.m4r in Resources */,
3407500E203E5436004596AE /* Silk.m4r in Resources */,
34075004203E5436004596AE /* Illuminate.m4r in Resources */,
B633C5D21A1D190B0059AC12 /* savephoto@2x.png in Resources */,
B10C9B611A7049EC00ECA2BF /* play_icon.png in Resources */,
34074FF3203E5436004596AE /* hello.m4r in Resources */,
34074FF9203E5436004596AE /* synth.m4r in Resources */,
AD83FF401A73426500B5C81A /* audio_pause_button_blue@2x.png in Resources */,
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */,
34CF0788203E6B78005C4D61 /* ringback_tone_ansi.caf in Resources */,
34074FF7203E5436004596AE /* popcorn.m4r in Resources */,
34CF0789203E6B78005C4D61 /* ringback_tone_cept.caf in Resources */,
34074FFF203E5436004596AE /* Circuit.m4r in Resources */,
34074FF8203E5436004596AE /* pulse.m4r in Resources */,
4517642A1DE939FD00EDB8B9 /* ContactCell.xib in Resources */,
AD83FF431A73426500B5C81A /* audio_play_button@2x.png in Resources */,
34075007203E5436004596AE /* Playtime.m4r in Resources */,
45CB2FA81CB7146C00E1B343 /* Launch Screen.storyboard in Resources */,
34B3F8781E8DF1700035BE1A /* ContactsPicker.xib in Resources */,
B633C5C31A1D190B0059AC12 /* mute_off@2x.png in Resources */,
3407500F203E5436004596AE /* Slow Rise.m4r in Resources */,
34074FF2203E5436004596AE /* complete.m4r in Resources */,
34074FFB203E5436004596AE /* Beacon.m4r in Resources */,
AD83FF411A73426500B5C81A /* audio_play_button_blue@2x.png in Resources */,
FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */,
E1370BE018A0686600826894 /* busy.mp3 in Resources */,
E1370BE218A0686C00826894 /* failure.mp3 in Resources */,
B625CD561ABB589C00E8B23C /* NewMessage.aifc in Resources */,
34075014203E5436004596AE /* Waves.m4r in Resources */,
34075011203E5436004596AE /* Summit.m4r in Resources */,
34075006203E5436004596AE /* Opening.m4r in Resources */,
34074FF6203E5436004596AE /* note.m4r in Resources */,
34075009203E5436004596AE /* Radar.m4r in Resources */,
34075012203E5436004596AE /* Twinkle.m4r in Resources */,
B633C58D1A1D190B0059AC12 /* contact_default_feed.png in Resources */,
B10C9B621A7049EC00ECA2BF /* play_icon@2x.png in Resources */,
34074FFE203E5436004596AE /* Chimes.m4r in Resources */,
B633C5861A1D190B0059AC12 /* call@2x.png in Resources */,
B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */,
E1370BE418A0686C00826894 /* outring.mp3 in Resources */,
34074FF5203E5436004596AE /* keys.m4r in Resources */,
3407500D203E5436004596AE /* Signal.m4r in Resources */,
34075000203E5436004596AE /* Constellation.m4r in Resources */,
B10C9B601A7049EC00ECA2BF /* pause_icon@2x.png in Resources */,
E1370BE518A0686C00826894 /* r.caf in Resources */,
34075002203E5436004596AE /* Crystals.m4r in Resources */,
FC9120411A39EFB70074545C /* qr@2x.png in Resources */,
E1370BE618A0686C00826894 /* sonarping.mp3 in Resources */,
34075001203E5436004596AE /* Cosmic.m4r in Resources */,
34074FFD203E5436004596AE /* By The Seaside.m4r in Resources */,
34075013203E5436004596AE /* Uplift.m4r in Resources */,
3407500B203E5436004596AE /* Ripples.m4r in Resources */,
34CF0787203E6B78005C4D61 /* busy_tone_ansi.caf in Resources */,
34075010203E5436004596AE /* Stargaze.m4r in Resources */,
34074FF0203E5436004596AE /* chord.m4r in Resources */,
34074FF4203E5436004596AE /* input.m4r in Resources */,
B10C9B5F1A7049EC00ECA2BF /* pause_icon.png in Resources */,
3407500A203E5436004596AE /* Radiate.m4r in Resources */,
AD83FF471A73428300B5C81A /* audio_play_button_blue.png in Resources */,
34074FFC203E5436004596AE /* Bulletin.m4r in Resources */,
34074FEE203E5436004596AE /* aurora.m4r in Resources */,
34330A5E1E787BD800DF2FB9 /* ElegantIcons.ttf in Resources */,
AD83FF451A73426500B5C81A /* audio_pause_button@2x.png in Resources */,
);
@ -2782,6 +2960,7 @@
347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */,
346129761FD1E0B500532771 /* WeakTimer.swift in Sources */,
346129F81FD5F31400532771 /* OWS100RemoveTSRecipientsMigration.m in Sources */,
34074F61203D0CBE004596AE /* OWSSounds.m in Sources */,
346129B51FD1F7E800532771 /* OWSProfileManager.m in Sources */,
346129701FD1D74C00532771 /* Release.m in Sources */,
3478506C1FD9B78A007B8332 /* NoopNotificationsManager.swift in Sources */,
@ -2977,6 +3156,7 @@
34D1F0B11F867BFC0066283D /* OWSUnreadIndicatorCell.m in Sources */,
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */,
34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */,
34074F5B203D093B004596AE /* OWSSoundSettingsViewController.m in Sources */,
34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */,
B609597C1C2C0FC6004E8797 /* iRate.m in Sources */,
4574A5D61DD6704700C6B692 /* CallService.swift in Sources */,

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -10,9 +10,9 @@
#import "ConversationViewItem.h"
#import "DateUtil.h"
#import "DebugUIPage.h"
#import "DebugUITableViewController.h"
#import "FingerprintViewController.h"
#import "HomeViewController.h"
#import "DebugUITableViewController.h"
#import "MediaDetailViewController.h"
#import "NSString+OWS.h"
#import "NotificationsManager.h"
@ -51,6 +51,7 @@
#import <SignalMessaging/OWSLogger.h>
#import <SignalMessaging/OWSPreferences.h>
#import <SignalMessaging/OWSProfileManager.h>
#import <SignalMessaging/OWSSounds.h>
#import <SignalMessaging/Release.h>
#import <SignalMessaging/ThreadUtil.h>
#import <SignalMessaging/UIColor+OWS.h>

View File

@ -1,9 +1,10 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "NotificationSettingsViewController.h"
#import "NotificationSettingsOptionsViewController.h"
#import "OWSSoundSettingsViewController.h"
#import <SignalMessaging/Environment.h>
#import <SignalMessaging/OWSPreferences.h>
@ -30,7 +31,34 @@
__weak NotificationSettingsViewController *weakSelf = self;
OWSPreferences *prefs = [Environment preferences];
// Sounds section.
OWSTableSection *soundsSection = [OWSTableSection new];
soundsSection.headerTitle = NSLocalizedString(@"SETTINGS_SECTION_SOUNDS",
@"Label for the sounds section of settings views.");
[soundsSection
addItem:[OWSTableItem disclosureItemWithText:
NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
@"Label for settings view that allows user to change the notification sound.")
actionBlock:^{
OWSSoundSettingsViewController *vc =
[OWSSoundSettingsViewController new];
vc.soundType = OWSSoundType_Notification;
[weakSelf.navigationController pushViewController:vc animated:YES];
}]];
[soundsSection
addItem:[OWSTableItem disclosureItemWithText:
NSLocalizedString(@"SETTINGS_ITEM_RINGTONE_SOUND",
@"Label for settings view that allows user to change the ringtone sound.")
actionBlock:^{
OWSSoundSettingsViewController *vc =
[OWSSoundSettingsViewController new];
vc.soundType = OWSSoundType_Ringtone;
[weakSelf.navigationController pushViewController:vc animated:YES];
}]];
[contents addSection:soundsSection];
OWSTableSection *backgroundSection = [OWSTableSection new];
backgroundSection.headerTitle = NSLocalizedString(@"NOTIFICATIONS_SECTION_BACKGROUND", nil);
[backgroundSection addItem:[OWSTableItem itemWithCustomCellBlock:^{

View File

@ -8,6 +8,7 @@
#import "FingerprintViewController.h"
#import "OWSAddToContactViewController.h"
#import "OWSBlockingManager.h"
#import "OWSSoundSettingsViewController.h"
#import "PhoneNumber.h"
#import "ShowGroupMembersViewController.h"
#import "Signal-Swift.h"
@ -566,6 +567,37 @@ NS_ASSUME_NONNULL_BEGIN
[contents addSection:section];
}
// Sounds section.
OWSTableSection *soundsSection = [OWSTableSection new];
soundsSection.headerTitle = NSLocalizedString(@"SETTINGS_SECTION_SOUNDS",
@"Label for the sounds section of settings views.");
[soundsSection
addItem:[OWSTableItem disclosureItemWithText:
NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
@"Label for settings view that allows user to change the notification sound.")
actionBlock:^{
OWSSoundSettingsViewController *vc =
[OWSSoundSettingsViewController new];
vc.soundType = OWSSoundType_Notification;
vc.thread = weakSelf.thread;
[weakSelf.navigationController pushViewController:vc animated:YES];
}]];
if (!self.isGroupThread) {
[soundsSection
addItem:[OWSTableItem disclosureItemWithText:
NSLocalizedString(@"SETTINGS_ITEM_RINGTONE_SOUND",
@"Label for settings view that allows user to change the ringtone sound.")
actionBlock:^{
OWSSoundSettingsViewController *vc =
[OWSSoundSettingsViewController new];
vc.soundType = OWSSoundType_Ringtone;
vc.thread = weakSelf.thread;
[weakSelf.navigationController pushViewController:vc animated:YES];
}]];
}
[contents addSection:soundsSection];
self.contents = contents;
}

View File

@ -0,0 +1,26 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSTableViewController.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, OWSSoundType) {
OWSSoundType_Notification = 0,
OWSSoundType_Ringtone,
};
@class TSThread;
@interface OWSSoundSettingsViewController : OWSTableViewController
@property (nonatomic) OWSSoundType soundType;
// This property is optional. If it is not set, we are
// editing the global notification sound.
@property (nonatomic, nullable) TSThread *thread;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,165 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSSoundSettingsViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <SignalMessaging/OWSSounds.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSSoundSettingsViewController ()
@property (nonatomic) BOOL isDirty;
@property (nonatomic) OWSSound currentSound;
@property (nonatomic) AVAudioPlayer *audioPlayer;
@end
#pragma mark -
@implementation OWSSoundSettingsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
switch (self.soundType) {
case OWSSoundType_Notification:
[self setTitle:NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
@"Label for settings view that allows user to change the notification sound.")];
self.currentSound
= (self.thread ? [OWSSounds notificationSoundForThread:self.thread] : [OWSSounds globalNotificationSound]);
break;
case OWSSoundType_Ringtone:
[self setTitle:NSLocalizedString(@"SETTINGS_ITEM_RINGTONE_SOUND",
@"Label for settings view that allows user to change the ringtone sound.")];
self.currentSound
= (self.thread ? [OWSSounds ringtoneSoundForThread:self.thread] : [OWSSounds globalRingtoneSound]);
break;
}
[self updateTableContents];
[self updateNavigationItems];
}
- (void)viewDidAppear:(BOOL)animated
{
[self updateTableContents];
}
- (void)updateNavigationItems
{
self.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:@selector(cancelWasPressed:)];
if (self.isDirty) {
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self
action:@selector(saveWasPressed:)];
} else {
self.navigationItem.rightBarButtonItem = nil;
}
}
#pragma mark - Table Contents
- (void)updateTableContents
{
OWSTableContents *contents = [OWSTableContents new];
__weak OWSSoundSettingsViewController *weakSelf = self;
OWSTableSection *soundsSection = [OWSTableSection new];
soundsSection.headerTitle = NSLocalizedString(
@"NOTIFICATIONS_SECTION_SOUNDS", @"Label for settings UI that allows user to change the notification sound.");
NSArray<NSNumber *> *allSounds;
switch (self.soundType) {
case OWSSoundType_Notification:
allSounds = [OWSSounds allNotificationSounds];
break;
case OWSSoundType_Ringtone:
allSounds = [OWSSounds allRingtoneSounds];
break;
}
for (NSNumber *nsValue in allSounds) {
OWSSound sound = (OWSSound)nsValue.intValue;
OWSTableItem *item;
if (sound == self.currentSound) {
item = [OWSTableItem checkmarkItemWithText:[OWSSounds displayNameForSound:sound]
actionBlock:^{
[weakSelf soundWasSelected:sound];
}];
} else {
item = [OWSTableItem actionItemWithText:[OWSSounds displayNameForSound:sound]
actionBlock:^{
[weakSelf soundWasSelected:sound];
}];
}
[soundsSection addItem:item];
}
[contents addSection:soundsSection];
self.contents = contents;
}
#pragma mark - Events
- (void)soundWasSelected:(OWSSound)sound
{
[self.audioPlayer stop];
self.audioPlayer = [OWSSounds audioPlayerForSound:sound];
// Suppress looping in this view.
self.audioPlayer.numberOfLoops = 0;
[self.audioPlayer play];
if (self.currentSound == sound) {
return;
}
self.currentSound = sound;
self.isDirty = YES;
[self updateTableContents];
[self updateNavigationItems];
}
- (void)cancelWasPressed:(id)sender
{
// TODO: Add "discard changes?" alert.
[self.audioPlayer stop];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)saveWasPressed:(id)sender
{
switch (self.soundType) {
case OWSSoundType_Notification:
if (self.thread) {
[OWSSounds setNotificationSound:self.currentSound forThread:self.thread];
} else {
[OWSSounds setGlobalNotificationSound:self.currentSound];
}
break;
case OWSSoundType_Ringtone:
if (self.thread) {
[OWSSounds setRingtoneSound:self.currentSound forThread:self.thread];
} else {
[OWSSounds setGlobalRingtoneSound:self.currentSound];
}
break;
}
[self.audioPlayer stop];
[self.navigationController popViewControllerAnimated:YES];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -37,7 +37,7 @@ struct AudioSource: Hashable {
let localizedName = isBuiltInEarPiece ? UIDevice.current.localizedModel : portDescription.portName
self.init(localizedName: localizedName,
image:#imageLiteral(resourceName: "button_phone_white"), // TODO
image: #imageLiteral(resourceName: "button_phone_white"), // TODO
isBuiltInSpeaker: false,
isBuiltInEarPiece: isBuiltInEarPiece,
portDescription: portDescription)
@ -102,42 +102,6 @@ protocol CallAudioServiceDelegate: class {
}
}
class Sound: NSObject {
static let incomingRing = Sound(filePath: "r", fileExtension: "caf", loop: true)
static let outgoingRing = Sound(filePath: "outring", fileExtension: "mp3", loop: true)
static let dialing = Sound(filePath: "sonarping", fileExtension: "mp3", loop: true)
static let busy = Sound(filePath: "busy", fileExtension: "mp3", loop: false)
static let failure = Sound(filePath: "failure", fileExtension: "mp3", loop: false)
let filePath: String
let fileExtension: String
let url: URL
let loop: Bool
init(filePath: String, fileExtension: String, loop: Bool) {
self.filePath = filePath
self.fileExtension = fileExtension
self.url = Bundle.main.url(forResource: self.filePath, withExtension: self.fileExtension)!
self.loop = loop
}
lazy var player: AVAudioPlayer? = {
let newPlayer: AVAudioPlayer?
do {
try newPlayer = AVAudioPlayer(contentsOf: self.url, fileTypeHint: nil)
if self.loop {
newPlayer?.numberOfLoops = -1
}
} catch {
owsFail("\(self.logTag) failed to build audio player with error: \(error)")
newPlayer = nil
}
return newPlayer
}()
}
// MARK: Vibration config
private let vibrateRepeatDuration = 1.6
@ -175,7 +139,7 @@ protocol CallAudioServiceDelegate: class {
internal func stateDidChange(call: SignalCall, state: CallState) {
AssertIsOnMainThread()
self.handleState(call:call)
self.handleState(call: call)
}
internal func muteDidChange(call: SignalCall, isMuted: Bool) {
@ -340,7 +304,7 @@ protocol CallAudioServiceDelegate: class {
// HACK: Without this async, dialing sound only plays once. I don't really understand why. Does the audioSession
// need some time to settle? Is somethign else interrupting our session?
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
self.play(sound: Sound.dialing)
self.play(sound: OWSSound.callConnecting)
}
}
@ -353,7 +317,7 @@ protocol CallAudioServiceDelegate: class {
Logger.debug("\(self.logTag) \(#function)")
AssertIsOnMainThread()
self.play(sound: Sound.outgoingRing)
self.play(sound: OWSSound.callOutboundRinging)
}
private func handleLocalRinging(call: SignalCall) {
@ -372,7 +336,7 @@ protocol CallAudioServiceDelegate: class {
Logger.debug("\(self.logTag) \(#function)")
AssertIsOnMainThread()
play(sound: Sound.failure)
play(sound: OWSSound.callFailure)
handleCallEnded(call: call)
}
@ -389,14 +353,14 @@ protocol CallAudioServiceDelegate: class {
vibrate()
handleCallEnded(call:call)
handleCallEnded(call: call)
}
private func handleBusy(call: SignalCall) {
Logger.debug("\(self.logTag) \(#function)")
AssertIsOnMainThread()
play(sound: Sound.busy)
play(sound: OWSSound.callBusy)
// Let the busy sound play for 4 seconds. The full file is longer than necessary
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 4.0) {
@ -422,12 +386,12 @@ protocol CallAudioServiceDelegate: class {
stopAnyRingingVibration()
}
private func play(sound: Sound) {
guard let newPlayer = sound.player else {
owsFail("\(self.logTag) unable to build player")
private func play(sound: OWSSound) {
guard let newPlayer = OWSSounds.audioPlayer(for: sound) else {
owsFail("\(self.logTag) unable to build player for sound: \(OWSSounds.displayName(for: sound))")
return
}
Logger.info("\(self.logTag) playing sound: \(sound.filePath)")
Logger.info("\(self.logTag) playing sound: \(OWSSounds.displayName(for: sound))")
// It's important to stop the current player **before** starting the new player. In the case that
// we're playing the same sound, since the player is memoized on the sound instance, we'd otherwise
@ -449,7 +413,8 @@ protocol CallAudioServiceDelegate: class {
self?.ringVibration()
}
vibrateTimer?.fire()
play(sound: Sound.incomingRing)
let sound = OWSSounds.ringtoneSound(for: call.thread)
play(sound: sound)
}
private func stopAnyRingingVibration() {

View File

@ -46,7 +46,7 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate {
let iconMaskImage = #imageLiteral(resourceName: "logoSignal")
providerConfiguration.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage)
providerConfiguration.ringtoneSound = "r.caf"
// We set the ringtoneSound property later.
return providerConfiguration
}
@ -113,7 +113,7 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate {
if Environment.current().preferences.isCallKitPrivacyEnabled() {
let callKitId = CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString
update.remoteHandle = CXHandle(type: .generic, value: callKitId)
TSStorageManager.shared().setPhoneNumber(call.remotePhoneNumber, forCallKitId:callKitId)
TSStorageManager.shared().setPhoneNumber(call.remotePhoneNumber, forCallKitId: callKitId)
update.localizedCallerName = NSLocalizedString("CALLKIT_ANONYMOUS_CONTACT_NAME", comment: "The generic name used for calls if CallKit privacy is enabled")
} else {
update.localizedCallerName = self.contactsManager.stringForConversationTitle(withPhoneIdentifier: call.remotePhoneNumber)
@ -124,6 +124,12 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate {
disableUnsupportedFeatures(callUpdate: update)
// Update the provider configuration to reflect the caller's ringtone.
let sound = OWSSounds.ringtoneSound(for: call.thread)
let providerConfiguration = provider.configuration
providerConfiguration.ringtoneSound = OWSSounds.filename(for: sound)
provider.configuration = providerConfiguration
// Report the incoming call to the system
provider.reportNewIncomingCall(with: call.localId, update: update) { error in
/*

View File

@ -10,6 +10,7 @@
#import <SignalMessaging/NSString+OWS.h>
#import <SignalMessaging/OWSContactsManager.h>
#import <SignalMessaging/OWSPreferences.h>
#import <SignalMessaging/OWSSounds.h>
#import <SignalServiceKit/NSString+SSK.h>
#import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSContactThread.h>
@ -18,11 +19,8 @@
#import <SignalServiceKit/TextSecureKitEnv.h>
#import <SignalServiceKit/Threading.h>
NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
@interface NotificationsManager ()
@property (nonatomic) SystemSoundID newMessageSound;
@property (nonatomic, readonly) NSMutableDictionary<NSString *, UILocalNotification *> *currentNotifications;
@property (nonatomic, readonly) NotificationType notificationPreviewType;
@ -43,9 +41,6 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
_currentNotifications = [NSMutableDictionary new];
NSURL *newMessageURL = [[NSBundle mainBundle] URLForResource:@"NewMessage" withExtension:@"aifc"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)newMessageURL, &_newMessageSound);
_notificationHistory = [NSMutableArray new];
OWSSingletonAssert();
@ -65,7 +60,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
UILocalNotification *notification = [UILocalNotification new];
notification.category = PushManagerCategoriesIncomingCall;
// Rather than using notification sounds, we control the ringtone and repeat vibrations with the CallAudioManager.
notification.soundName = @"r.caf";
OWSSound sound = [OWSSounds ringtoneSoundForThread:call.thread];
notification.soundName = [OWSSounds filenameForSound:sound];
NSString *localCallId = call.localId.UUIDString;
notification.userInfo = @{ PushManagerUserInfoKeysLocalCallId : localCallId };
@ -105,7 +101,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
};
if ([self shouldPlaySoundForNotification]) {
notification.soundName = kNotificationsManagerNewMesssageSoundName;
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
notification.soundName = [OWSSounds filenameForSound:sound];
}
NSString *alertMessage;
@ -144,7 +141,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
Signal_Thread_UserInfo_Key : thread.uniqueId
};
if ([self shouldPlaySoundForNotification]) {
notification.soundName = kNotificationsManagerNewMesssageSoundName;
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
notification.soundName = [OWSSounds filenameForSound:sound];
}
NSString *alertMessage;
@ -184,7 +182,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
Signal_Thread_UserInfo_Key : thread.uniqueId
};
if ([self shouldPlaySoundForNotification]) {
notification.soundName = kNotificationsManagerNewMesssageSoundName;
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
notification.soundName = [OWSSounds filenameForSound:sound];
}
NSString *alertMessage;
@ -228,7 +227,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.userInfo = @{ Signal_Thread_UserInfo_Key : thread.uniqueId };
if (shouldPlaySound) {
notification.soundName = kNotificationsManagerNewMesssageSoundName;
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
notification.soundName = [OWSSounds filenameForSound:sound];
}
NSString *alertBodyString = @"";
@ -248,7 +248,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
[[PushManager sharedManager] presentNotification:notification checkForCancel:NO];
} else {
if (shouldPlaySound && [Environment.preferences soundInForeground]) {
AudioServicesPlayAlertSound(_newMessageSound);
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
[OWSSounds playSound:sound];
}
}
});
@ -289,7 +290,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && messageText) {
UILocalNotification *notification = [[UILocalNotification alloc] init];
if (shouldPlaySound) {
notification.soundName = kNotificationsManagerNewMesssageSoundName;
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
notification.soundName = [OWSSounds filenameForSound:sound];
}
switch (self.notificationPreviewType) {
@ -351,7 +353,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc";
[[PushManager sharedManager] presentNotification:notification checkForCancel:YES];
} else {
if (shouldPlaySound && [Environment.preferences soundInForeground]) {
AudioServicesPlayAlertSound(_newMessageSound);
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
[OWSSounds playSound:sound];
}
}
});

View File

@ -1155,6 +1155,9 @@
/* No comment provided by engineer. */
"NOTIFICATIONS_SECTION_INAPP" = "In-App Notifications";
/* Label for settings UI that allows user to change the notification sound. */
"NOTIFICATIONS_SECTION_SOUNDS" = "Sounds";
/* No comment provided by engineer. */
"NOTIFICATIONS_SENDER_AND_MESSAGE" = "Sender name & message";
@ -1566,6 +1569,12 @@
/* content of tweet when inviting via twitter */
"SETTINGS_INVITE_TWITTER_TEXT" = "You can reach me using Signal by @WhisperSystems, get it now.";
/* Label for settings view that allows user to change the notification sound. */
"SETTINGS_ITEM_NOTIFICATION_SOUND" = "Notification";
/* Label for settings view that allows user to change the ringtone sound. */
"SETTINGS_ITEM_RINGTONE_SOUND" = "Ringtone";
/* Title for settings activity */
"SETTINGS_NAV_BAR_TITLE" = "Settings";
@ -1596,6 +1605,9 @@
/* Settings table section footer. */
"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Call Integration shows Signal calls on your lock screen and in the system's call history. You may optionally show your contact's name and number. If iCloud is enabled, this call history will be shared with Apple.";
/* Label for the sounds section of settings views. */
"SETTINGS_SECTION_SOUNDS" = "Sounds";
/* settings topic header for table section */
"SETTINGS_SECTION_TITLE_CALLING" = "Calling";

View File

@ -29,6 +29,7 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
#import <SignalMessaging/OWSLogger.h>
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/OWSProfileManager.h>
#import <SignalMessaging/OWSSounds.h>
#import <SignalMessaging/OWSTableViewController.h>
#import <SignalMessaging/OWSUserProfile.h>
#import <SignalMessaging/Release.h>

View File

@ -76,6 +76,12 @@ typedef UITableViewCell *_Nonnull (^OWSTableCustomCellBlock)(void);
customRowHeight:(CGFloat)customRowHeight
actionBlock:(nullable OWSTableActionBlock)actionBlock;
+ (OWSTableItem *)checkmarkItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock;
+ (OWSTableItem *)itemWithText:(NSString *)text
actionBlock:(nullable OWSTableActionBlock)actionBlock
accessoryType:(UITableViewCellAccessoryType)accessoryType;
+ (OWSTableItem *)subPageItemWithText:(NSString *)text actionBlock:(nullable OWSTableSubPageBlock)actionBlock;
+ (OWSTableItem *)subPageItemWithText:(NSString *)text

View File

@ -147,20 +147,31 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f;
}
+ (OWSTableItem *)disclosureItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock
{
return [self itemWithText:text actionBlock:actionBlock accessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
+ (OWSTableItem *)checkmarkItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock
{
return [self itemWithText:text actionBlock:actionBlock accessoryType:UITableViewCellAccessoryCheckmark];
}
+ (OWSTableItem *)itemWithText:(NSString *)text
actionBlock:(nullable OWSTableActionBlock)actionBlock
accessoryType:(UITableViewCellAccessoryType)accessoryType
{
OWSAssert(text.length > 0);
OWSAssert(actionBlock);
OWSTableItem *item = [OWSTableItem new];
item.itemType = OWSTableItemTypeAction;
__weak OWSTableItem *weakItem = item;
item.actionBlock = actionBlock;
item.customCellBlock = ^{
UITableViewCell *cell = [UITableViewCell new];
cell.textLabel.text = text;
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.textLabel.textColor = [UIColor blackColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryType = accessoryType;
return cell;
};
return item;

View File

@ -0,0 +1,97 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, OWSSound) {
OWSSound_Default = 0,
// Notification Sounds
OWSSound_Aurora,
OWSSound_Bamboo,
OWSSound_Chord,
OWSSound_Circles,
OWSSound_Complete,
OWSSound_Hello,
OWSSound_Input,
OWSSound_Keys,
OWSSound_Note,
OWSSound_Popcorn,
OWSSound_Pulse,
OWSSound_Synth,
// Ringtone Sounds
OWSSound_Apex,
OWSSound_Beacon,
OWSSound_Bulletin,
OWSSound_By_The_Seaside,
OWSSound_Chimes,
OWSSound_Circuit,
OWSSound_Constellation,
OWSSound_Cosmic,
OWSSound_Crystals,
OWSSound_Hillside,
OWSSound_Illuminate,
OWSSound_Night_Owl,
OWSSound_Opening,
OWSSound_Playtime,
OWSSound_Presto,
OWSSound_Radar,
OWSSound_Radiate,
OWSSound_Ripples,
OWSSound_Sencha,
OWSSound_Signal,
OWSSound_Silk,
OWSSound_Slow_Rise,
OWSSound_Stargaze,
OWSSound_Summit,
OWSSound_Twinkle,
OWSSound_Uplift,
OWSSound_Waves,
// Calls
OWSSound_CallConnecting,
OWSSound_CallOutboundRinging,
OWSSound_CallBusy,
OWSSound_CallFailure,
};
@class AVAudioPlayer;
@class TSThread;
@interface OWSSounds : NSObject
- (instancetype)init NS_UNAVAILABLE;
+ (NSString *)displayNameForSound:(OWSSound)sound;
+ (NSString *)filenameForSound:(OWSSound)sound;
+ (void)playSound:(OWSSound)sound;
#pragma mark - Notifications
+ (NSArray<NSNumber *> *)allNotificationSounds;
+ (OWSSound)globalNotificationSound;
+ (void)setGlobalNotificationSound:(OWSSound)sound;
+ (OWSSound)notificationSoundForThread:(TSThread *)thread;
+ (void)setNotificationSound:(OWSSound)sound forThread:(TSThread *)thread;
#pragma mark - Ringtones
+ (NSArray<NSNumber *> *)allRingtoneSounds;
+ (OWSSound)globalRingtoneSound;
+ (void)setGlobalRingtoneSound:(OWSSound)sound;
+ (OWSSound)ringtoneSoundForThread:(TSThread *)thread;
+ (void)setRingtoneSound:(OWSSound)sound forThread:(TSThread *)thread;
#pragma mark - Calls
+ (nullable AVAudioPlayer *)audioPlayerForSound:(OWSSound)sound;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,463 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSSounds.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioServices.h>
#import <SignalServiceKit/TSStorageManager.h>
#import <SignalServiceKit/TSThread.h>
#import <SignalServiceKit/YapDatabaseConnection+OWS.h>
NSString *const kOWSSoundsStorageNotificationCollection = @"kOWSSoundsStorageNotificationCollection";
NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlobalNotificationKey";
NSString *const kOWSSoundsStorageRingtoneCollection = @"kOWSSoundsStorageRingtoneCollection";
NSString *const kOWSSoundsStorageGlobalRingtoneKey = @"kOWSSoundsStorageGlobalRingtoneKey";
@interface OWSSounds ()
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@property (nonatomic) NSMutableDictionary<NSNumber *, NSNumber *> *systemSoundIDMap;
@end
#pragma mark -
@implementation OWSSounds
+ (instancetype)sharedManager
{
static OWSSounds *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] initDefault];
});
return instance;
}
- (instancetype)initDefault
{
TSStorageManager *storageManager = [TSStorageManager sharedManager];
return [self initWithStorageManager:storageManager];
}
- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager
{
self = [super init];
if (!self) {
return self;
}
OWSAssert(storageManager);
_dbConnection = storageManager.newDatabaseConnection;
// TODO: Is it safe to load all of these sounds into memory?
// Probably better to do LRU cache.
self.systemSoundIDMap = [NSMutableDictionary new];
OWSSingletonAssert();
return self;
}
+ (NSArray<NSNumber *> *)allNotificationSounds
{
return @[
@(OWSSound_Aurora),
@(OWSSound_Bamboo),
@(OWSSound_Chord),
@(OWSSound_Circles),
@(OWSSound_Complete),
@(OWSSound_Hello),
@(OWSSound_Input),
@(OWSSound_Keys),
@(OWSSound_Note),
@(OWSSound_Popcorn),
@(OWSSound_Pulse),
@(OWSSound_Synth),
];
}
+ (NSArray<NSNumber *> *)allRingtoneSounds
{
return @[
@(OWSSound_Apex),
@(OWSSound_Beacon),
@(OWSSound_Bulletin),
@(OWSSound_By_The_Seaside),
@(OWSSound_Chimes),
@(OWSSound_Circuit),
@(OWSSound_Constellation),
@(OWSSound_Cosmic),
@(OWSSound_Crystals),
@(OWSSound_Hillside),
@(OWSSound_Illuminate),
@(OWSSound_Night_Owl),
@(OWSSound_Opening),
@(OWSSound_Playtime),
@(OWSSound_Presto),
@(OWSSound_Radar),
@(OWSSound_Radiate),
@(OWSSound_Ripples),
@(OWSSound_Sencha),
@(OWSSound_Signal),
@(OWSSound_Silk),
@(OWSSound_Slow_Rise),
@(OWSSound_Stargaze),
@(OWSSound_Summit),
@(OWSSound_Twinkle),
@(OWSSound_Uplift),
@(OWSSound_Waves),
];
}
+ (NSString *)displayNameForSound:(OWSSound)sound
{
// TODO: Should we localize these sound names?
switch (sound) {
case OWSSound_Default:
OWSFail(@"%@ invalid argument.", self.logTag);
return @"";
// Notification Sounds
case OWSSound_Aurora:
return @"Aurora";
case OWSSound_Bamboo:
return @"Bamboo";
case OWSSound_Chord:
return @"Chord";
case OWSSound_Circles:
return @"Circles";
case OWSSound_Complete:
return @"Complete";
case OWSSound_Hello:
return @"Hello";
case OWSSound_Input:
return @"Input";
case OWSSound_Keys:
return @"Keys";
case OWSSound_Note:
return @"Note";
case OWSSound_Popcorn:
return @"Popcorn";
case OWSSound_Pulse:
return @"Pulse";
case OWSSound_Synth:
return @"Synth";
// Ringtone Sounds
case OWSSound_Apex:
return @"Apex";
case OWSSound_Beacon:
return @"Beacon";
case OWSSound_Bulletin:
return @"Bulletin";
case OWSSound_By_The_Seaside:
return @"By The Seaside";
case OWSSound_Chimes:
return @"Chimes";
case OWSSound_Circuit:
return @"Circuit";
case OWSSound_Constellation:
return @"Constellation";
case OWSSound_Cosmic:
return @"Cosmic";
case OWSSound_Crystals:
return @"Crystals";
case OWSSound_Hillside:
return @"Hillside";
case OWSSound_Illuminate:
return @"Illuminate";
case OWSSound_Night_Owl:
return @"Night Owl";
case OWSSound_Opening:
return @"Opening";
case OWSSound_Playtime:
return @"Playtime";
case OWSSound_Presto:
return @"Presto";
case OWSSound_Radar:
return @"Radar";
case OWSSound_Radiate:
return @"Radiate";
case OWSSound_Ripples:
return @"Ripples";
case OWSSound_Sencha:
return @"Sencha";
case OWSSound_Signal:
return @"Signal";
case OWSSound_Silk:
return @"Silk";
case OWSSound_Slow_Rise:
return @"Slow Rise";
case OWSSound_Stargaze:
return @"Stargaze";
case OWSSound_Summit:
return @"Summit";
case OWSSound_Twinkle:
return @"Twinkle";
case OWSSound_Uplift:
return @"Uplift";
case OWSSound_Waves:
return @"Waves";
// Calls
case OWSSound_CallConnecting:
return @"Call Connecting";
case OWSSound_CallOutboundRinging:
return @"Call Outboung Ringing";
case OWSSound_CallBusy:
return @"Call Busy";
case OWSSound_CallFailure:
return @"Call Failure";
}
}
+ (NSString *)filenameForSound:(OWSSound)sound
{
switch (sound) {
case OWSSound_Default:
OWSFail(@"%@ invalid argument.", self.logTag);
return @"";
// Notification Sounds
case OWSSound_Aurora:
return @"aurora.m4r";
case OWSSound_Bamboo:
return @"bamboo.m4r";
case OWSSound_Chord:
return @"chord.m4r";
case OWSSound_Circles:
return @"circles.m4r";
case OWSSound_Complete:
return @"complete.m4r";
case OWSSound_Hello:
return @"hello.m4r";
case OWSSound_Input:
return @"input.m4r";
case OWSSound_Keys:
return @"keys.m4r";
case OWSSound_Note:
return @"note.m4r";
case OWSSound_Popcorn:
return @"popcorn.m4r";
case OWSSound_Pulse:
return @"pulse.m4r";
case OWSSound_Synth:
return @"synth.m4r";
// Ringtone Sounds
case OWSSound_Apex:
return @"Apex.m4r";
case OWSSound_Beacon:
return @"Beacon.m4r";
case OWSSound_Bulletin:
return @"Bulletin.m4r";
case OWSSound_By_The_Seaside:
return @"By The Seaside.m4r";
case OWSSound_Chimes:
return @"Chimes.m4r";
case OWSSound_Circuit:
return @"Circuit.m4r";
case OWSSound_Constellation:
return @"Constellation.m4r";
case OWSSound_Cosmic:
return @"Cosmic.m4r";
case OWSSound_Crystals:
return @"Crystals.m4r";
case OWSSound_Hillside:
return @"Hillside.m4r";
case OWSSound_Illuminate:
return @"Illuminate.m4r";
case OWSSound_Night_Owl:
return @"Night Owl.m4r";
case OWSSound_Opening:
return @"Opening.m4r";
case OWSSound_Playtime:
return @"Playtime.m4r";
case OWSSound_Presto:
return @"Presto.m4r";
case OWSSound_Radar:
return @"Radar.m4r";
case OWSSound_Radiate:
return @"Radiate.m4r";
case OWSSound_Ripples:
return @"Ripples.m4r";
case OWSSound_Sencha:
return @"Sencha.m4r";
case OWSSound_Signal:
return @"Signal.m4r";
case OWSSound_Silk:
return @"Silk.m4r";
case OWSSound_Slow_Rise:
return @"Slow Rise.m4r";
case OWSSound_Stargaze:
return @"Stargaze.m4r";
case OWSSound_Summit:
return @"Summit.m4r";
case OWSSound_Twinkle:
return @"Twinkle.m4r";
case OWSSound_Uplift:
return @"Uplift.m4r";
case OWSSound_Waves:
return @"Waves.m4r";
// Calls
case OWSSound_CallConnecting:
return @"ringback_tone_cept.caf";
case OWSSound_CallOutboundRinging:
return @"ringback_tone_ansi.caf";
case OWSSound_CallBusy:
return @"busy_tone_ansi.caf";
case OWSSound_CallFailure:
return @"end_call_tone_cept.caf";
}
}
+ (NSURL *)soundURLForSound:(OWSSound)sound
{
NSString *filename = [self filenameForSound:sound];
NSURL *_Nullable url = [[NSBundle mainBundle] URLForResource:filename.stringByDeletingPathExtension
withExtension:filename.pathExtension];
OWSAssert(url);
return url;
}
+ (void)playSound:(OWSSound)sound
{
[self.sharedManager playSound:sound];
}
- (SystemSoundID)systemSoundIDForSound:(OWSSound)sound
{
@synchronized(self)
{
NSNumber *_Nullable systemSoundID = self.systemSoundIDMap[@(sound)];
if (!systemSoundID) {
NSURL *soundURL = [OWSSounds soundURLForSound:sound];
SystemSoundID newSystemSoundID;
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &newSystemSoundID);
if (error) {
OWSFail(@"%@ could not load sound.", self.logTag);
}
systemSoundID = @(newSystemSoundID);
self.systemSoundIDMap[@(sound)] = systemSoundID;
}
return (SystemSoundID)systemSoundID.unsignedIntegerValue;
}
}
- (void)playSound:(OWSSound)sound
{
SystemSoundID systemSoundID = [self systemSoundIDForSound:sound];
AudioServicesPlayAlertSound(systemSoundID);
}
#pragma mark - Notifications
+ (OWSSound)defaultNotificationSound
{
return OWSSound_Note;
}
+ (OWSSound)globalNotificationSound
{
OWSSounds *instance = OWSSounds.sharedManager;
NSNumber *_Nullable value = [instance.dbConnection objectForKey:kOWSSoundsStorageGlobalNotificationKey
inCollection:kOWSSoundsStorageNotificationCollection];
// Default to the global default.
return (value ? (OWSSound)value.intValue : [self defaultNotificationSound]);
}
+ (void)setGlobalNotificationSound:(OWSSound)sound
{
OWSSounds *instance = OWSSounds.sharedManager;
[instance.dbConnection setObject:@(sound)
forKey:kOWSSoundsStorageGlobalNotificationKey
inCollection:kOWSSoundsStorageNotificationCollection];
}
+ (OWSSound)notificationSoundForThread:(TSThread *)thread
{
OWSSounds *instance = OWSSounds.sharedManager;
NSNumber *_Nullable value =
[instance.dbConnection objectForKey:thread.uniqueId inCollection:kOWSSoundsStorageNotificationCollection];
// Default to the "global" notification sound, which in turn will default to the global default.
return (value ? (OWSSound)value.intValue : [self globalNotificationSound]);
}
+ (void)setNotificationSound:(OWSSound)sound forThread:(TSThread *)thread
{
OWSSounds *instance = OWSSounds.sharedManager;
[instance.dbConnection setObject:@(sound)
forKey:thread.uniqueId
inCollection:kOWSSoundsStorageNotificationCollection];
}
#pragma mark - Ringtones
+ (OWSSound)defaultRingtoneSound
{
return OWSSound_Opening;
}
+ (OWSSound)globalRingtoneSound
{
OWSSounds *instance = OWSSounds.sharedManager;
NSNumber *_Nullable value = [instance.dbConnection objectForKey:kOWSSoundsStorageGlobalRingtoneKey
inCollection:kOWSSoundsStorageRingtoneCollection];
// Default to the global default.
return (value ? (OWSSound)value.intValue : [self defaultRingtoneSound]);
}
+ (void)setGlobalRingtoneSound:(OWSSound)sound
{
OWSSounds *instance = OWSSounds.sharedManager;
[instance.dbConnection setObject:@(sound)
forKey:kOWSSoundsStorageGlobalRingtoneKey
inCollection:kOWSSoundsStorageRingtoneCollection];
}
+ (OWSSound)ringtoneSoundForThread:(TSThread *)thread
{
OWSSounds *instance = OWSSounds.sharedManager;
NSNumber *_Nullable value =
[instance.dbConnection objectForKey:thread.uniqueId inCollection:kOWSSoundsStorageRingtoneCollection];
// Default to the "global" ringtone sound, which in turn will default to the global default.
return (value ? (OWSSound)value.intValue : [self globalRingtoneSound]);
}
+ (void)setRingtoneSound:(OWSSound)sound forThread:(TSThread *)thread
{
OWSSounds *instance = OWSSounds.sharedManager;
[instance.dbConnection setObject:@(sound) forKey:thread.uniqueId inCollection:kOWSSoundsStorageRingtoneCollection];
}
#pragma mark - Calls
+ (BOOL)shouldAudioPlayerLoopForSound:(OWSSound)sound
{
return (sound == OWSSound_CallConnecting || sound == OWSSound_CallOutboundRinging ||
[self.allRingtoneSounds containsObject:@(sound)]);
}
+ (nullable AVAudioPlayer *)audioPlayerForSound:(OWSSound)sound
{
NSURL *soundURL = [OWSSounds soundURLForSound:sound];
NSError *error;
AVAudioPlayer *_Nullable player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
if (error || !player) {
OWSFail(@"%@ audioPlayerForSound failed with error: %@.", self.logTag, error);
return nil;
}
if ([self shouldAudioPlayerLoopForSound:sound]) {
player.numberOfLoops = -1;
}
return player;
}
@end