diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index d8d79d7c2..7ff6dc67a 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -7829,7 +7829,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 523; + CURRENT_PROJECT_VERSION = 524; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7900,7 +7900,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 523; + CURRENT_PROJECT_VERSION = 524; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index d57ca2b39..c1cf8409b 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -121,7 +121,7 @@ extension ConversationVC: let threadId: String = self.viewModel.threadData.threadId guard - Permissions.hasMicrophonePermission, + Permissions.microphone == .granted, self.viewModel.threadData.threadVariant == .contact, Singleton.callManager.currentCall == nil, let call: SessionCall = Storage.shared.read({ [dependencies = viewModel.dependencies] db in @@ -323,7 +323,7 @@ extension ConversationVC: Permissions.requestMicrophonePermissionIfNeeded() - if !Permissions.hasMicrophonePermission { + if Permissions.microphone != .granted { SNLog("Proceeding without microphone access. Any recorded video will be silent.") } @@ -2487,7 +2487,7 @@ extension ConversationVC: // Keep screen on UIApplication.shared.isIdleTimerDisabled = false - guard Permissions.hasMicrophonePermission else { return } + guard Permissions.microphone == .granted else { return } // Cancel any current audio playback self.viewModel.stopAudio() diff --git a/Session/Conversations/Message Cells/CallMessageCell.swift b/Session/Conversations/Message Cells/CallMessageCell.swift index 31a639dc3..e121e2bc8 100644 --- a/Session/Conversations/Message Cells/CallMessageCell.swift +++ b/Session/Conversations/Message Cells/CallMessageCell.swift @@ -169,7 +169,7 @@ final class CallMessageCell: MessageCell { !Storage.shared[.areCallsEnabled] ) || ( messageInfo.state == .permissionDeniedMicrophone && - !Permissions.hasMicrophonePermission + Permissions.microphone != .granted ) ) infoImageViewWidthConstraint.constant = (shouldShowInfoIcon ? CallMessageCell.iconSize : 0) @@ -230,7 +230,7 @@ final class CallMessageCell: MessageCell { !Storage.shared[.areCallsEnabled] ) || ( messageInfo.state == .permissionDeniedMicrophone && - !Permissions.hasMicrophonePermission + Permissions.microphone != .granted ) else { return } diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index c20ebfe69..27c74611e 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -277,6 +277,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD Log.info("[AppDelegate] Setting 'isMainAppActive' to false.") UserDefaults.sharedLokiProject?[.isMainAppActive] = false + + Log.info("[AppDelegate] Setting 'lastSeenHasMicrophonePermission'.") + UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = (Permissions.microphone == .granted) Log.flush() } diff --git a/Session/Utilities/Permissions.swift b/Session/Utilities/Permissions.swift index 087218feb..e0f6a997f 100644 --- a/Session/Utilities/Permissions.swift +++ b/Session/Utilities/Permissions.swift @@ -91,8 +91,9 @@ extension Permissions { case .denied: handlePermissionDenied() case .undetermined: onNotGranted?() - AVAudioApplication.requestRecordPermission { _ in } - + AVAudioApplication.requestRecordPermission { granted in + UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = granted + } default: break } } else { @@ -101,8 +102,9 @@ extension Permissions { case .denied: handlePermissionDenied() case .undetermined: onNotGranted?() - AVAudioSession.sharedInstance().requestRecordPermission { _ in } - + AVAudioSession.sharedInstance().requestRecordPermission { granted in + UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = granted + } default: break } } diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift index 462d73174..228f9ba92 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift @@ -81,7 +81,7 @@ extension MessageReceiver { return } - guard db[.areCallsEnabled] && Permissions.hasMicrophonePermission else { + guard db[.areCallsEnabled] && Permissions.microphone == .granted else { let state: CallMessage.MessageInfo.State = (db[.areCallsEnabled] ? .permissionDeniedMicrophone : .permissionDenied) SNLog("[MessageReceiver+Calls] Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)") diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 789114e86..45a288a91 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -100,6 +100,15 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension (UserDefaults.sharedLokiProject?[.lastCallPreOffer]) != nil ) + let hasMicrophonePermission: Bool = { + return switch Permissions.microphone { + case .undetermined: + (UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission]).defaulting(to: false) + default: + Permissions.microphone == .granted + } + }() + // HACK: It is important to use write synchronously here to avoid a race condition // where the completeSilenty() is called before the local notification request // is added to notification center @@ -142,6 +151,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension using: dependencies ) + // FIXME: Do we need to call it here? It does nothing other than log what kind of message we received try MessageReceiver.handleCallMessage( db, threadId: threadId, @@ -154,7 +164,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension throw NotificationError.ignorableMessage } - switch ((db[.areCallsEnabled] && Permissions.hasMicrophonePermission), isCallOngoing) { + switch ((db[.areCallsEnabled] && hasMicrophonePermission), isCallOngoing) { case (false, _): Log.info("Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)") if diff --git a/SessionUtilitiesKit/General/SNUserDefaults.swift b/SessionUtilitiesKit/General/SNUserDefaults.swift index f5fa20112..ff6579913 100644 --- a/SessionUtilitiesKit/General/SNUserDefaults.swift +++ b/SessionUtilitiesKit/General/SNUserDefaults.swift @@ -34,6 +34,7 @@ public enum SNUserDefaults { case wasUnlinked case isMainAppActive case isCallOngoing + case lastSeenHasMicrophonePermission } public enum Date: Swift.String { diff --git a/SessionUtilitiesKit/Utilities/Permissions.swift b/SessionUtilitiesKit/Utilities/Permissions.swift index ae568019c..e8e907fcf 100644 --- a/SessionUtilitiesKit/Utilities/Permissions.swift +++ b/SessionUtilitiesKit/Utilities/Permissions.swift @@ -3,11 +3,37 @@ import AVFAudio public enum Permissions { - public static var hasMicrophonePermission: Bool { + + public enum MicrophonePermisson { + case denied + case granted + case undetermined + case unknown + } + + public static var microphone: MicrophonePermisson { if #available(iOSApplicationExtension 17.0, *) { - AVAudioApplication.shared.recordPermission == .granted + switch AVAudioApplication.shared.recordPermission { + case .undetermined: + return .undetermined + case .denied: + return .denied + case .granted: + return .granted + @unknown default: + return .unknown + } } else { - AVAudioSession.sharedInstance().recordPermission == .granted + switch AVAudioSession.sharedInstance().recordPermission { + case .undetermined: + return .undetermined + case .denied: + return .denied + case .granted: + return .granted + @unknown default: + return .unknown + } } } }