workaround for a permission issue in NotificationServiceExtension

pull/1061/head
Ryan ZHAO 10 months ago
parent 35ae44d389
commit a16e3aa61a

@ -7829,7 +7829,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 523; CURRENT_PROJECT_VERSION = 524;
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -7900,7 +7900,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 523; CURRENT_PROJECT_VERSION = 524;
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

@ -121,7 +121,7 @@ extension ConversationVC:
let threadId: String = self.viewModel.threadData.threadId let threadId: String = self.viewModel.threadData.threadId
guard guard
Permissions.hasMicrophonePermission, Permissions.microphone == .granted,
self.viewModel.threadData.threadVariant == .contact, self.viewModel.threadData.threadVariant == .contact,
Singleton.callManager.currentCall == nil, Singleton.callManager.currentCall == nil,
let call: SessionCall = Storage.shared.read({ [dependencies = viewModel.dependencies] db in let call: SessionCall = Storage.shared.read({ [dependencies = viewModel.dependencies] db in
@ -323,7 +323,7 @@ extension ConversationVC:
Permissions.requestMicrophonePermissionIfNeeded() Permissions.requestMicrophonePermissionIfNeeded()
if !Permissions.hasMicrophonePermission { if Permissions.microphone != .granted {
SNLog("Proceeding without microphone access. Any recorded video will be silent.") SNLog("Proceeding without microphone access. Any recorded video will be silent.")
} }
@ -2487,7 +2487,7 @@ extension ConversationVC:
// Keep screen on // Keep screen on
UIApplication.shared.isIdleTimerDisabled = false UIApplication.shared.isIdleTimerDisabled = false
guard Permissions.hasMicrophonePermission else { return } guard Permissions.microphone == .granted else { return }
// Cancel any current audio playback // Cancel any current audio playback
self.viewModel.stopAudio() self.viewModel.stopAudio()

@ -169,7 +169,7 @@ final class CallMessageCell: MessageCell {
!Storage.shared[.areCallsEnabled] !Storage.shared[.areCallsEnabled]
) || ( ) || (
messageInfo.state == .permissionDeniedMicrophone && messageInfo.state == .permissionDeniedMicrophone &&
!Permissions.hasMicrophonePermission Permissions.microphone != .granted
) )
) )
infoImageViewWidthConstraint.constant = (shouldShowInfoIcon ? CallMessageCell.iconSize : 0) infoImageViewWidthConstraint.constant = (shouldShowInfoIcon ? CallMessageCell.iconSize : 0)
@ -230,7 +230,7 @@ final class CallMessageCell: MessageCell {
!Storage.shared[.areCallsEnabled] !Storage.shared[.areCallsEnabled]
) || ( ) || (
messageInfo.state == .permissionDeniedMicrophone && messageInfo.state == .permissionDeniedMicrophone &&
!Permissions.hasMicrophonePermission Permissions.microphone != .granted
) )
else { return } else { return }

@ -278,6 +278,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
Log.info("[AppDelegate] Setting 'isMainAppActive' to false.") Log.info("[AppDelegate] Setting 'isMainAppActive' to false.")
UserDefaults.sharedLokiProject?[.isMainAppActive] = false UserDefaults.sharedLokiProject?[.isMainAppActive] = false
Log.info("[AppDelegate] Setting 'lastSeenHasMicrophonePermission'.")
UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = (Permissions.microphone == .granted)
Log.flush() Log.flush()
} }

@ -91,8 +91,9 @@ extension Permissions {
case .denied: handlePermissionDenied() case .denied: handlePermissionDenied()
case .undetermined: case .undetermined:
onNotGranted?() onNotGranted?()
AVAudioApplication.requestRecordPermission { _ in } AVAudioApplication.requestRecordPermission { granted in
UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = granted
}
default: break default: break
} }
} else { } else {
@ -101,8 +102,9 @@ extension Permissions {
case .denied: handlePermissionDenied() case .denied: handlePermissionDenied()
case .undetermined: case .undetermined:
onNotGranted?() onNotGranted?()
AVAudioSession.sharedInstance().requestRecordPermission { _ in } AVAudioSession.sharedInstance().requestRecordPermission { granted in
UserDefaults.sharedLokiProject?[.lastSeenHasMicrophonePermission] = granted
}
default: break default: break
} }
} }

@ -81,7 +81,7 @@ extension MessageReceiver {
return return
} }
guard db[.areCallsEnabled] && Permissions.hasMicrophonePermission else { guard db[.areCallsEnabled] && Permissions.microphone == .granted else {
let state: CallMessage.MessageInfo.State = (db[.areCallsEnabled] ? .permissionDeniedMicrophone : .permissionDenied) let state: CallMessage.MessageInfo.State = (db[.areCallsEnabled] ? .permissionDeniedMicrophone : .permissionDenied)
SNLog("[MessageReceiver+Calls] Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)") SNLog("[MessageReceiver+Calls] Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)")

@ -100,6 +100,15 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
(UserDefaults.sharedLokiProject?[.lastCallPreOffer]) != nil (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 // HACK: It is important to use write synchronously here to avoid a race condition
// where the completeSilenty() is called before the local notification request // where the completeSilenty() is called before the local notification request
// is added to notification center // is added to notification center
@ -142,6 +151,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
using: dependencies 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( try MessageReceiver.handleCallMessage(
db, db,
threadId: threadId, threadId: threadId,
@ -154,7 +164,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
throw NotificationError.ignorableMessage throw NotificationError.ignorableMessage
} }
switch ((db[.areCallsEnabled] && Permissions.hasMicrophonePermission), isCallOngoing) { switch ((db[.areCallsEnabled] && hasMicrophonePermission), isCallOngoing) {
case (false, _): case (false, _):
Log.info("Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)") Log.info("Microphone permission is \(AVAudioSession.sharedInstance().recordPermission)")
if if

@ -34,6 +34,7 @@ public enum SNUserDefaults {
case wasUnlinked case wasUnlinked
case isMainAppActive case isMainAppActive
case isCallOngoing case isCallOngoing
case lastSeenHasMicrophonePermission
} }
public enum Date: Swift.String { public enum Date: Swift.String {

@ -3,11 +3,37 @@
import AVFAudio import AVFAudio
public enum Permissions { 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, *) { 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 { } 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
}
} }
} }
} }

Loading…
Cancel
Save