ios: reverted some changes related to lockScreen (#2011)

* Revert "ios: CallKit enhancements (#2010)"

This reverts commit 840df89ca6.

* Revert "ios: CallKit integrated with app lock and screen protect (#2007)"

This reverts commit 0404b020e6.

* ios: reverted some changes related to lockScreen

* undo delay

* better support of appLock + call

* refactor

* refactor 2

* refactor 3

* refactor 4

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
Stanislav Dmitrenko
2023-03-16 00:09:33 +03:00
committed by GitHub
parent 840df89ca6
commit 2643ea9066
6 changed files with 88 additions and 86 deletions
-10
View File
@@ -94,16 +94,6 @@ class AppDelegate: NSObject, UIApplicationDelegate {
return configuration
}
func applicationProtectedDataWillBecomeUnavailable(_ application: UIApplication) {
logger.debug("AppDelegate: will lock screen")
ChatModel.shared.onLockScreenCurrently = true
}
func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
logger.debug("AppDelegate: did unlock screen")
ChatModel.shared.onLockScreenCurrently = false
}
private func receiveMessages(_ completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let complete = BGManager.shared.completionHandler {
logger.debug("AppDelegate: completed BGManager.receiveMessages")
+79 -46
View File
@@ -27,48 +27,64 @@ struct ContentView: View {
var body: some View {
ZStack {
contentView()
if chatModel.showCallView, let call = chatModel.activeCall {
ActiveCallView(call: call, canConnectCall: $canConnectCall)
}
if prefPerformLA && userAuthorized != true {
Rectangle().fill(colorScheme == .dark ? .black : .white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onTapGesture(perform: {})
Button(action: runAuthenticate) { Label("Unlock", systemImage: "lock") }
} else if let status = chatModel.chatDbStatus, status != .ok {
DatabaseErrorView(status: status)
} else if !chatModel.v3DBMigration.startChat {
MigrateToAppGroupView()
} else if let step = chatModel.onboardingStage, (!chatModel.showCallView || chatModel.activeCall == nil) {
if case .onboardingComplete = step,
chatModel.currentUser != nil {
mainView()
} else {
OnboardingView(onboarding: step)
}
callView(call)
}
}
.onAppear {
logger.debug("ContentView: canConnectCall \(canConnectCall), doAuthenticate \(doAuthenticate)")
if doAuthenticate { runAuthenticate() }
if prefPerformLA { requestNtfAuthorization() }
initAuthenticate()
}
.onChange(of: doAuthenticate) { _ in
initAuthenticate()
}
.onChange(of: doAuthenticate) { _ in if doAuthenticate { runAuthenticate() } }
.alert(isPresented: $alertManager.presentAlert) { alertManager.alertView! }
}
@ViewBuilder private func contentView() -> some View {
if prefPerformLA && userAuthorized != true {
lockButton()
} else if let status = chatModel.chatDbStatus, status != .ok {
DatabaseErrorView(status: status)
} else if !chatModel.v3DBMigration.startChat {
MigrateToAppGroupView()
} else if let step = chatModel.onboardingStage {
if case .onboardingComplete = step,
chatModel.currentUser != nil {
mainView()
} else {
OnboardingView(onboarding: step)
}
}
}
@ViewBuilder private func callView(_ call: Call) -> some View {
if CallController.useCallKit() {
ActiveCallView(call: call, canConnectCall: Binding.constant(true))
.onDisappear {
if userAuthorized == false && doAuthenticate { runAuthenticate() }
}
} else {
ActiveCallView(call: call, canConnectCall: $canConnectCall)
if prefPerformLA && userAuthorized != true {
Rectangle()
.fill(colorScheme == .dark ? .black : .white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
lockButton()
}
}
}
private func lockButton() -> some View {
Button(action: runAuthenticate) { Label("Unlock", systemImage: "lock") }
}
private func mainView() -> some View {
ZStack(alignment: .top) {
ChatListView().privacySensitive(protectScreen)
.onAppear {
NtfManager.shared.requestAuthorization(
onDeny: {
if (!notificationAlertShown) {
notificationAlertShown = true
alertManager.showAlert(notificationAlert())
}
},
onAuthorized: { notificationAlertShown = false }
)
if !prefPerformLA { requestNtfAuthorization() }
// Local Authentication notice is to be shown on next start after onboarding is complete
if (!prefLANoticeShown && prefShowLANotice && !chatModel.chats.isEmpty) {
prefLANoticeShown = true
@@ -93,24 +109,29 @@ struct ContentView: View {
}
// private func processUserActivity(_ activity: NSUserActivity) {
// let intent = activity.interaction?.intent
// if let contacts = (intent as? INStartCallIntent)?.contacts {
// callToContact(contacts, .audio)
// } else if let contacts = (intent as? INStartAudioCallIntent)?.contacts {
// callToContact(contacts, .audio)
// } else if let contacts = (intent as? INStartVideoCallIntent)?.contacts {
// callToContact(contacts, .video)
// }
// }
//
// private func callToContact(_ contacts: [INPerson], _ mediaType: CallMediaType) {
// if let contactId = contacts.first?.personHandle?.value,
// let chatInfo = chatModel.chats.first(where: { $0.id == contactId })?.chatInfo,
// case let .direct(contact) = chatInfo {
// CallController.shared.startCall(contact, mediaType)
// let callToContact = { (contactId: ChatId?, mediaType: CallMediaType) in
// if let chatInfo = chatModel.chats.first(where: { $0.id == contactId })?.chatInfo,
// case let .direct(contact) = chatInfo {
// CallController.shared.startCall(contact, mediaType)
// }
// }
// if let intent = activity.interaction?.intent as? INStartCallIntent {
// callToContact(intent.contacts?.first?.personHandle?.value, .audio)
// } else if let intent = activity.interaction?.intent as? INStartAudioCallIntent {
// callToContact(intent.contacts?.first?.personHandle?.value, .audio)
// } else if let intent = activity.interaction?.intent as? INStartVideoCallIntent {
// callToContact(intent.contacts?.first?.personHandle?.value, .video)
// }
// }
private func initAuthenticate() {
if CallController.useCallKit() && chatModel.showCallView && chatModel.activeCall != nil {
userAuthorized = false
} else if doAuthenticate {
runAuthenticate()
}
}
private func runAuthenticate() {
if !prefPerformLA {
userAuthorized = true
@@ -134,13 +155,25 @@ struct ContentView: View {
break
case .unavailable:
userAuthorized = true
canConnectCall = true
prefPerformLA = false
canConnectCall = true
AlertManager.shared.showAlert(laUnavailableTurningOffAlert())
}
}
}
func requestNtfAuthorization() {
NtfManager.shared.requestAuthorization(
onDeny: {
if (!notificationAlertShown) {
notificationAlertShown = true
alertManager.showAlert(notificationAlert())
}
},
onAuthorized: { notificationAlertShown = false }
)
}
func laNoticeAlert() -> Alert {
Alert(
title: Text("SimpleX Lock"),
-3
View File
@@ -59,9 +59,6 @@ final class ChatModel: ObservableObject {
@Published var draft: ComposeState?
@Published var draftChatId: String?
var sceneWasActiveAtLeastOnce = false
var onLockScreenCurrently = false
var messageDelivery: Dictionary<Int64, () -> Void> = [:]
var filesToDelete: [String] = []
+1 -3
View File
@@ -20,8 +20,8 @@ struct SimpleXApp: App {
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
@State private var userAuthorized: Bool?
@State private var doAuthenticate = false
@State private var canConnectCall = false
@State private var enteredBackground: TimeInterval? = nil
@State private var canConnectCall = false
@State private var lastSuccessfulUnlock: TimeInterval? = nil
init() {
@@ -66,7 +66,6 @@ struct SimpleXApp: App {
NtfManager.shared.setNtfBadgeCount(chatModel.totalUnreadCountForAllUsers())
case .active:
CallController.shared.onEndCall = nil
chatModel.sceneWasActiveAtLeastOnce = true
let appState = appStateGroupDefault.get()
startChatAndActivate()
if appState.inactive && chatModel.chatRunning == true {
@@ -116,7 +115,6 @@ struct SimpleXApp: App {
}
}
private func unlockedRecently() -> Bool {
if let lastSuccessfulUnlock = lastSuccessfulUnlock {
return ProcessInfo.processInfo.systemUptime - lastSuccessfulUnlock < 2
@@ -12,12 +12,12 @@ import SimpleXChat
struct ActiveCallView: View {
@EnvironmentObject var m: ChatModel
@Environment(\.scenePhase) var scenePhase
@ObservedObject var call: Call
@Binding var canConnectCall: Bool
@Environment(\.scenePhase) var scenePhase
@State private var client: WebRTCClient? = nil
@State private var activeCall: WebRTCClient.Call? = nil
@State private var localRendererAspectRatio: CGFloat? = nil
@Binding var canConnectCall: Bool
var body: some View {
ZStack(alignment: .bottom) {
@@ -38,7 +38,7 @@ struct ActiveCallView: View {
}
}
.onAppear {
logger.debug("ActiveCallView: appear client is nil \(client == nil), canConnectCall \(canConnectCall, privacy: .public), scenePhase \(String(describing: scenePhase), privacy: .public)")
logger.debug("ActiveCallView: appear client is nil \(client == nil), scenePhase \(String(describing: scenePhase), privacy: .public), canConnectCall \(canConnectCall)")
createWebRTCClient()
}
.onChange(of: canConnectCall) { _ in
@@ -55,22 +55,8 @@ struct ActiveCallView: View {
}
private func createWebRTCClient() {
if client == nil && (canConnectCall || m.onLockScreenCurrently) {
createWebRTCClientWithoutWait()
} else if (!m.sceneWasActiveAtLeastOnce) {
// This code waits a second until it recheck `sceneWasActiveAtLeastOnce`.
// It helps to know whether a call from lockscreen or not.
// After the second `sceneWasActiveAtLeastOnce` will still be false when the call from lockscreen
Task {
try? await Task.sleep(nanoseconds: 1_000_000_000)
createWebRTCClientWithoutWait()
}
}
}
private func createWebRTCClientWithoutWait() {
if client == nil && (canConnectCall || !m.sceneWasActiveAtLeastOnce || m.onLockScreenCurrently) {
client = WebRTCClient($activeCall, { msg in await MainActor.run {processRtcMessage(msg: msg)} }, $localRendererAspectRatio)
if client == nil && canConnectCall {
client = WebRTCClient($activeCall, { msg in await MainActor.run { processRtcMessage(msg: msg) } }, $localRendererAspectRatio)
sendCommandToClient()
}
}
@@ -97,7 +97,6 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
print("received", #function)
logger.debug("CallController: activating audioSession and audio in WebRTCClient")
RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
RTCAudioSession.sharedInstance().isAudioEnabled = true
@@ -113,7 +112,6 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
print("received", #function)
logger.debug("CallController: deactivating audioSession and audio in WebRTCClient")
RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession)
RTCAudioSession.sharedInstance().isAudioEnabled = false
@@ -265,7 +263,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func endCall(callUUID: UUID) {
logger.debug("CallController: ending the call")
logger.debug("CallController: ending the call with UUID \(callUUID.uuidString)")
if CallController.useCallKit() {
requestTransaction(with: CXEndCallAction(call: callUUID))
} else {
@@ -280,7 +278,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func endCall(invitation: RcvCallInvitation) {
logger.debug("CallController: ending the call")
logger.debug("CallController: ending the call with invitation")
callManager.endCall(invitation: invitation) {
if invitation.contact.id == self.activeCallInvitation?.contact.id {
DispatchQueue.main.async {
@@ -291,7 +289,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func endCall(call: Call, completed: @escaping () -> Void) {
logger.debug("CallController: ending the call")
logger.debug("CallController: ending the call with call instance")
callManager.endCall(call: call, completed: completed)
}