add delay on permission chain for calls

pull/1061/head
Ryan ZHAO 2 weeks ago
parent c4ac8bbe46
commit fc4b349d36

@ -147,7 +147,8 @@ class SendMediaNavigationController: UINavigationController {
}
private func didTapCameraModeButton() {
Permissions.requestCameraPermissionIfNeeded(using: dependencies) { [weak self] in
Permissions.requestCameraPermissionIfNeeded(using: dependencies) { [weak self] granted in
guard granted else { return }
DispatchQueue.main.async {
self?.fadeTo(viewControllers: ((self?.captureViewController).map { [$0] } ?? []))
}

@ -133,6 +133,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
)
/// Do a little migration on an educated guess of if the user has been asked for local network permission based on calls permission
dependencies[defaults: .standard, key: .hasRequestedLocalNetworkPermission] = dependencies[singleton: .storage, key: .areCallsEnabled]
/// Now that the theme settings have been applied we can complete the migrations
self?.completePostMigrationSetup(calledFrom: .finishLaunching)
},
@ -291,7 +294,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// On every activation, clear old temp directories.
dependencies[singleton: .fileManager].clearOldTemporaryDirectories()
if dependencies[singleton: .storage, key: .areCallsEnabled] {
if dependencies[singleton: .storage, key: .areCallsEnabled] && dependencies[defaults: .standard, key: .hasRequestedLocalNetworkPermission] {
Permissions.checkLocalNetworkPermission(using: dependencies)
}
}

@ -613,7 +613,8 @@ private final class ScanQRCodePlaceholderVC: UIViewController {
}
@objc private func requestCameraAccess() {
Permissions.requestCameraPermissionIfNeeded(using: dependencies) { [weak self] in
Permissions.requestCameraPermissionIfNeeded(using: dependencies) { [weak self] granted in
guard granted else { return }
self?.joinOpenGroupVC?.handleCameraAccessGranted()
}
}

@ -90,6 +90,7 @@ class PrivacySettingsViewModel: SessionTableViewModel, NavigationItemSource, Nav
let typingIndicatorsEnabled: Bool
let areLinkPreviewsEnabled: Bool
let areCallsEnabled: Bool
let localNetworkPermission: Bool
}
let title: String = "sessionPrivacy".localized()
@ -102,7 +103,8 @@ class PrivacySettingsViewModel: SessionTableViewModel, NavigationItemSource, Nav
areReadReceiptsEnabled: db[.areReadReceiptsEnabled],
typingIndicatorsEnabled: db[.typingIndicatorsEnabled],
areLinkPreviewsEnabled: db[.areLinkPreviewsEnabled],
areCallsEnabled: db[.areCallsEnabled]
areCallsEnabled: db[.areCallsEnabled],
localNetworkPermission: db[.lastSeenHasLocalNetworkPermission]
)
}
.mapWithPrevious { [dependencies] previous, current -> [SectionModel] in
@ -132,9 +134,7 @@ class PrivacySettingsViewModel: SessionTableViewModel, NavigationItemSource, Nav
confirmStyle: .danger,
cancelStyle: .alert_text,
onConfirm: { _ in
Permissions.requestMicrophonePermissionIfNeeded(using: dependencies)
Permissions.requestCameraPermissionIfNeeded(using: dependencies)
Permissions.requestLocalNetworkPermissionIfNeeded(using: dependencies)
Permissions.requestPermissionsForCalls(using: dependencies)
}
),
onTap: { [weak self] in
@ -192,8 +192,8 @@ class PrivacySettingsViewModel: SessionTableViewModel, NavigationItemSource, Nav
title: "Local Network",
subtitle: "Allow access to local network to facilitate voice and video calls",
trailingAccessory: .toggle(
Permissions.localNetwork(using: dependencies) == .granted,
oldValue: Permissions.localNetwork(using: dependencies) == .granted,
current.localNetworkPermission,
oldValue: (previous ?? current).localNetworkPermission,
accessibility: Accessibility(
identifier: "Local Network Permission - Switch"
)
@ -406,9 +406,7 @@ class PrivacySettingsViewModel: SessionTableViewModel, NavigationItemSource, Nav
confirmStyle: .danger,
cancelStyle: .alert_text,
onConfirm: { [dependencies] _ in
Permissions.requestMicrophonePermissionIfNeeded(using: dependencies)
Permissions.requestCameraPermissionIfNeeded(using: dependencies)
Permissions.requestLocalNetworkPermissionIfNeeded(using: dependencies)
Permissions.requestPermissionsForCalls(using: dependencies)
dependencies[singleton: .storage].write { db in
try db.setAndUpdateConfig(
.areCallsEnabled,

@ -74,7 +74,8 @@ struct ScanQRCodeScreen: View {
}
private func requestCameraAccess() {
Permissions.requestCameraPermissionIfNeeded(using: dependencies) {
Permissions.requestCameraPermissionIfNeeded(using: dependencies) { granted in
guard granted else { return }
hasCameraAccess.toggle()
}
}

@ -13,11 +13,11 @@ extension Permissions {
@discardableResult public static func requestCameraPermissionIfNeeded(
presentingViewController: UIViewController? = nil,
using dependencies: Dependencies,
onAuthorized: (() -> Void)? = nil
onAuthorized: ((Bool) -> Void)? = nil
) -> Bool {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
onAuthorized?()
onAuthorized?(true)
return true
case .denied, .restricted:
@ -45,8 +45,8 @@ extension Permissions {
return false
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video, completionHandler: { _ in
onAuthorized?()
AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in
onAuthorized?(granted)
})
return false
@ -57,6 +57,7 @@ extension Permissions {
public static func requestMicrophonePermissionIfNeeded(
presentingViewController: UIViewController? = nil,
using dependencies: Dependencies,
onAuthorized: ((Bool) -> Void)? = nil,
onNotGranted: (() -> Void)? = nil
) {
let handlePermissionDenied: () -> Void = {
@ -94,6 +95,7 @@ extension Permissions {
onNotGranted?()
AVAudioApplication.requestRecordPermission { granted in
dependencies[defaults: .appGroup, key: .lastSeenHasMicrophonePermission] = granted
onAuthorized?(granted)
}
default: break
}
@ -105,6 +107,7 @@ extension Permissions {
onNotGranted?()
AVAudioSession.sharedInstance().requestRecordPermission { granted in
dependencies[defaults: .appGroup, key: .lastSeenHasMicrophonePermission] = granted
onAuthorized?(granted)
}
default: break
}
@ -167,7 +170,15 @@ extension Permissions {
}
}
// MARK: - Local Network Premission
public static func localNetwork(using dependencies: Dependencies) -> Status {
let status: Bool = dependencies[singleton: .storage, key: .lastSeenHasLocalNetworkPermission]
return status ? .granted : .denied
}
public static func requestLocalNetworkPermissionIfNeeded(using dependencies: Dependencies) {
dependencies[defaults: .standard, key: .hasRequestedLocalNetworkPermission] = true
checkLocalNetworkPermission(using: dependencies)
}
@ -176,10 +187,14 @@ extension Permissions {
do {
if try await checkLocalNetworkPermissionWithBonjour() {
// Permission is granted, continue to next onboarding step
dependencies[defaults: .appGroup, key: .lastSeenHasLocalNetworkPermission] = true
dependencies[singleton: .storage].writeAsync { db in
db[.lastSeenHasLocalNetworkPermission] = true
}
} else {
// Permission denied, explain why we need it and show button to open Settings
dependencies[defaults: .appGroup, key: .lastSeenHasLocalNetworkPermission] = false
dependencies[singleton: .storage].writeAsync { db in
db[.lastSeenHasLocalNetworkPermission] = false
}
}
} catch {
// Networking failure, handle error
@ -301,5 +316,30 @@ extension Permissions {
browser.cancel()
}
}
public static func requestPermissionsForCalls(
presentingViewController: UIViewController? = nil,
using dependencies: Dependencies
) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
requestMicrophonePermissionIfNeeded(
presentingViewController: presentingViewController,
using: dependencies,
onAuthorized: { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
requestCameraPermissionIfNeeded(
presentingViewController: presentingViewController,
using: dependencies,
onAuthorized: { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
requestLocalNetworkPermissionIfNeeded(using: dependencies)
}
}
)
}
}
)
}
}
}

@ -76,6 +76,10 @@ public extension Setting.BoolKey {
/// Controls whether developer mode is enabled (this displays a section within the Settings screen which allows manual control of feature flags
/// and system settings for better debugging)
static let developerModeEnabled: Setting.BoolKey = "developerModeEnabled"
/// There is no native api to get local network permission, so we need to modify the state and store in database to update UI accordingly.
/// Remove this in the future if Apple provides native api
static let lastSeenHasLocalNetworkPermission: Setting.BoolKey = "lastSeenHasLocalNetworkPermission"
}
// stringlint:ignore_contents

@ -110,8 +110,8 @@ public extension UserDefaults.BoolKey {
/// Indicates whether we had the microphone permission the last time the app when to the background
static let lastSeenHasMicrophonePermission: UserDefaults.BoolKey = "lastSeenHasMicrophonePermission"
/// Indicates whether we had the local network permission
static let lastSeenHasLocalNetworkPermission: UserDefaults.BoolKey = "lastSeenHasLocalNetworkPermission"
/// Indicates whether we had asked for the local network permission
static let hasRequestedLocalNetworkPermission: UserDefaults.BoolKey = "hasRequestedLocalNetworkPermission"
}
public extension UserDefaults.DateKey {

@ -50,9 +50,4 @@ public enum Permissions {
return .unknown
}
}
public static func localNetwork(using dependencies: Dependencies) -> Status {
let status: Bool = dependencies[defaults:.appGroup, key: .lastSeenHasLocalNetworkPermission]
return status ? .granted : .denied
}
}

Loading…
Cancel
Save