diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 569aadfef..c423f2c19 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -139,6 +139,7 @@ 7B0EFDEE274F598600FFAAE7 /* TimestampUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDED274F598600FFAAE7 /* TimestampUtils.swift */; }; 7B0EFDF0275084AA00FFAAE7 /* CallMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDEF275084AA00FFAAE7 /* CallMessageCell.swift */; }; 7B0EFDF2275449AA00FFAAE7 /* TSInfoMessage+Calls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDF1275449AA00FFAAE7 /* TSInfoMessage+Calls.swift */; }; + 7B0EFDF4275490EA00FFAAE7 /* ringing.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 7B0EFDF3275490EA00FFAAE7 /* ringing.mp3 */; }; 7B1581E2271E743B00848B49 /* OWSSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E1271E743B00848B49 /* OWSSounds.swift */; }; 7B1581E4271FC59D00848B49 /* CallModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E3271FC59C00848B49 /* CallModal.swift */; }; 7B1581E6271FD2A100848B49 /* VideoPreviewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E5271FD2A100848B49 /* VideoPreviewVC.swift */; }; @@ -149,7 +150,7 @@ 7B7CB18B270591630079FF93 /* ShareLogsModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB18A270591630079FF93 /* ShareLogsModal.swift */; }; 7B7CB18E270D066F0079FF93 /* IncomingCallBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB18D270D066F0079FF93 /* IncomingCallBanner.swift */; }; 7B7CB190270FB2150079FF93 /* MiniCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB18F270FB2150079FF93 /* MiniCallView.swift */; }; - 7B7CB192271508AD0079FF93 /* Vibration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB191271508AD0079FF93 /* Vibration.swift */; }; + 7B7CB192271508AD0079FF93 /* CallRingTonePlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB191271508AD0079FF93 /* CallRingTonePlayer.swift */; }; 7BA68909272A27BE00EFC32F /* SessionCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA68908272A27BE00EFC32F /* SessionCall.swift */; }; 7BA6890D27325CCC00EFC32F /* SessionCallManager+CXCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */; }; 7BA6890F27325CE300EFC32F /* SessionCallManager+CXProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */; }; @@ -1131,6 +1132,7 @@ 7B0EFDED274F598600FFAAE7 /* TimestampUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimestampUtils.swift; sourceTree = ""; }; 7B0EFDEF275084AA00FFAAE7 /* CallMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallMessageCell.swift; sourceTree = ""; }; 7B0EFDF1275449AA00FFAAE7 /* TSInfoMessage+Calls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSInfoMessage+Calls.swift"; sourceTree = ""; }; + 7B0EFDF3275490EA00FFAAE7 /* ringing.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = ringing.mp3; sourceTree = ""; }; 7B1581E1271E743B00848B49 /* OWSSounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSSounds.swift; sourceTree = ""; }; 7B1581E3271FC59C00848B49 /* CallModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallModal.swift; sourceTree = ""; }; 7B1581E5271FD2A100848B49 /* VideoPreviewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPreviewVC.swift; sourceTree = ""; }; @@ -1142,7 +1144,7 @@ 7B7CB18A270591630079FF93 /* ShareLogsModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareLogsModal.swift; sourceTree = ""; }; 7B7CB18D270D066F0079FF93 /* IncomingCallBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingCallBanner.swift; sourceTree = ""; }; 7B7CB18F270FB2150079FF93 /* MiniCallView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MiniCallView.swift; sourceTree = ""; }; - 7B7CB191271508AD0079FF93 /* Vibration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vibration.swift; sourceTree = ""; }; + 7B7CB191271508AD0079FF93 /* CallRingTonePlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallRingTonePlayer.swift; sourceTree = ""; }; 7BA68908272A27BE00EFC32F /* SessionCall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCall.swift; sourceTree = ""; }; 7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXCallController.swift"; sourceTree = ""; }; 7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXProvider.swift"; sourceTree = ""; }; @@ -1953,6 +1955,7 @@ 34074F54203D0722004596AE /* Sounds */ = { isa = PBXGroup; children = ( + 7B0EFDF3275490EA00FFAAE7 /* ringing.mp3 */, 45A2F004204473A3002E978A /* NewMessage.aifc */, 34661FB720C1C0D60056EDD6 /* message_sent.aiff */, 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */, @@ -2373,7 +2376,7 @@ C38EF23D255B6D66007E1867 /* UIView+OWS.h */, C38EF23E255B6D66007E1867 /* UIView+OWS.m */, C38EF2EF255B6DBB007E1867 /* Weak.swift */, - 7B7CB191271508AD0079FF93 /* Vibration.swift */, + 7B7CB191271508AD0079FF93 /* CallRingTonePlayer.swift */, 7B0EFDED274F598600FFAAE7 /* TimestampUtils.swift */, ); path = General; @@ -4218,6 +4221,7 @@ 45A2F005204473A3002E978A /* NewMessage.aifc in Resources */, 45B74A882044AAB600CD42F8 /* aurora.aifc in Resources */, 45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */, + 7B0EFDF4275490EA00FFAAE7 /* ringing.mp3 in Resources */, 45B74A852044AAB600CD42F8 /* bamboo.aifc in Resources */, C3A01E06261D24C400290BEB /* storage-seed-1.der in Resources */, 45B74A782044AAB600CD42F8 /* bamboo-quiet.aifc in Resources */, @@ -4663,7 +4667,7 @@ C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */, C352A36D2557858E00338F3E /* NSTimer+Proxying.m in Sources */, C32C5A2D256DB849003C73A2 /* LKGroupUtilities.m in Sources */, - 7B7CB192271508AD0079FF93 /* Vibration.swift in Sources */, + 7B7CB192271508AD0079FF93 /* CallRingTonePlayer.swift in Sources */, C3C2ABD22553C6C900C340D1 /* Data+SecureRandom.swift in Sources */, B8856E09256F1676001CE70E /* UIDevice+featureSupport.swift in Sources */, B8856DEF256F161F001CE70E /* NSString+SSK.m in Sources */, diff --git a/Session/Calls/Call Management/SessionCallManager+CXProvider.swift b/Session/Calls/Call Management/SessionCallManager+CXProvider.swift index 44dd8025f..7b3fe2d3a 100644 --- a/Session/Calls/Call Management/SessionCallManager+CXProvider.swift +++ b/Session/Calls/Call Management/SessionCallManager+CXProvider.swift @@ -72,6 +72,7 @@ extension SessionCallManager: CXProviderDelegate { AssertIsOnMainThread() guard let call = self.currentCall else { return } call.webRTCSession.audioSessionDidActivate(audioSession) + if call.isOutgoing && !call.hasConnected { CallRingTonePlayer.shared.startPlayingRingTone() } } public func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { diff --git a/Session/Calls/Call Management/SessionCallManager.swift b/Session/Calls/Call Management/SessionCallManager.swift index a229f92cb..ef68ee87f 100644 --- a/Session/Calls/Call Management/SessionCallManager.swift +++ b/Session/Calls/Call Management/SessionCallManager.swift @@ -69,7 +69,7 @@ public final class SessionCallManager: NSObject { self.provider.reportOutgoingCall(with: call.callID, connectedAt: call.connectedDate) } } - callTimeOutTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { _ in + callTimeOutTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: false) { _ in guard let currentCall = self.currentCall else { return } currentCall.didTimeout = true self.endCall(currentCall) { error in diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index bd01d0560..af43db4f6 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -195,6 +195,7 @@ final class CallVC : UIViewController, VideoPreviewDelegate { } self.call.hasConnectedDidChange = { DispatchQueue.main.async { + CallRingTonePlayer.shared.stopPlayingRingTone() self.callInfoLabel.text = "Connected" self.minimizeButton.isHidden = false UIView.animate(withDuration: 0.5, delay: 1, options: [], animations: { diff --git a/Session/Calls/Views & Modals/IncomingCallBanner.swift b/Session/Calls/Views & Modals/IncomingCallBanner.swift index e5e80d40f..9ba23cf3f 100644 --- a/Session/Calls/Views & Modals/IncomingCallBanner.swift +++ b/Session/Calls/Views & Modals/IncomingCallBanner.swift @@ -173,11 +173,13 @@ final class IncomingCallBanner: UIView, UIGestureRecognizerDelegate { UIView.animate(withDuration: 0.5, delay: 0, options: [], animations: { self.alpha = 1.0 }, completion: nil) - Vibration.shared.startVibration() + CallRingTonePlayer.shared.startVibration() + CallRingTonePlayer.shared.startPlayingRingTone() } public func dismiss() { - Vibration.shared.stopVibrationIfPossible() + CallRingTonePlayer.shared.stopVibrationIfPossible() + CallRingTonePlayer.shared.stopPlayingRingTone() UIView.animate(withDuration: 0.5, delay: 0, options: [], animations: { self.alpha = 0.0 }, completion: { _ in diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index f90ec017c..03f15508c 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -48,12 +48,21 @@ extension AppDelegate { } } + private func insertCallInfoMessage(for message: CallMessage, using transaction: YapDatabaseReadWriteTransaction) -> TSInfoMessage { + let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction) + let infoMessage = TSInfoMessage.from(message, associatedWith: thread) + infoMessage.save(with: transaction) + return infoMessage + } + @objc func setUpCallHandling() { // Pre offer messages MessageReceiver.handleNewCallOfferMessageIfNeeded = { (message, transaction) in guard CurrentAppContext().isMainApp else { return } guard SSKPreferences.areCallsEnabled else { - // TODO: Show tips and insert a missing call message + let infoMessage = self.insertCallInfoMessage(for: message, using: transaction) + infoMessage.updateCallInfoMessage(.missed, using: transaction) + // TODO: add tips return } let callManager = AppEnvironment.shared.callManager @@ -63,10 +72,7 @@ extension AppDelegate { callManager.handleIncomingCallOfferInBusyState(offerMessage: message, using: transaction) return } - // Create incoming call message - let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction) - let infoMessage = TSInfoMessage.from(message, associatedWith: thread) - infoMessage.save(with: transaction) + let infoMessage = self.insertCallInfoMessage(for: message, using: transaction) // Handle UI if let caller = message.sender, let uuid = message.uuid { let call = SessionCall(for: caller, uuid: uuid, mode: .answer) diff --git a/Session/Meta/AudioFiles/ringing.mp3 b/Session/Meta/AudioFiles/ringing.mp3 new file mode 100644 index 000000000..547f7133c Binary files /dev/null and b/Session/Meta/AudioFiles/ringing.mp3 differ diff --git a/SessionUtilitiesKit/General/CallRingTonePlayer.swift b/SessionUtilitiesKit/General/CallRingTonePlayer.swift new file mode 100644 index 000000000..dde0cb87e --- /dev/null +++ b/SessionUtilitiesKit/General/CallRingTonePlayer.swift @@ -0,0 +1,37 @@ +import AudioToolbox +import AVFoundation + +public final class CallRingTonePlayer { + + public static let shared = CallRingTonePlayer() + + private var vibrationTimer: Timer? + private var player: AVAudioPlayer? + + public func startVibration() { + vibrationTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { _ in + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) + } + } + + public func stopVibrationIfPossible() { + vibrationTimer?.invalidate() + vibrationTimer = nil + } + + public func startPlayingRingTone() { + guard let url = Bundle.main.url(forResource: "ringing", withExtension: "mp3") else { return } + do { + player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue) + player?.numberOfLoops = -1 + player?.play() + } catch let error { + print(error.localizedDescription) + } + } + + public func stopPlayingRingTone() { + guard let player = player else { return } + player.stop() + } +} diff --git a/SessionUtilitiesKit/General/Vibration.swift b/SessionUtilitiesKit/General/Vibration.swift deleted file mode 100644 index 4e9aa2e6f..000000000 --- a/SessionUtilitiesKit/General/Vibration.swift +++ /dev/null @@ -1,19 +0,0 @@ -import AudioToolbox - -public final class Vibration { - - public static let shared = Vibration() - - private var vibrationTimer: Timer? - - public func startVibration() { - vibrationTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { _ in - AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) - } - } - - public func stopVibrationIfPossible() { - vibrationTimer?.invalidate() - vibrationTimer = nil - } -}