From 96787efe4c0df8a6f670b64dc03a99678bf84b2e Mon Sep 17 00:00:00 2001 From: QuentinArguillere Date: Fri, 2 Jul 2021 15:33:25 +0200 Subject: [PATCH] Move the currentCallContextBeforeGoingBackground from LinphoneManager to CallManager. When answering a callkit call, if app is not on foreground, disable the camera and save the call context in the CallManager to re-enable it when we return to foreground. --- Classes/CallManager.swift | 25 ++++++++++++--- Classes/CallView.m | 8 ++--- Classes/LinphoneAppDelegate.m | 58 ++++++++++++++++------------------ Classes/LinphoneManager.h | 8 ----- Classes/ProviderDelegate.swift | 6 ++++ 5 files changed, 57 insertions(+), 48 deletions(-) diff --git a/Classes/CallManager.swift b/Classes/CallManager.swift index e4954ef69..68c0869eb 100644 --- a/Classes/CallManager.swift +++ b/Classes/CallManager.swift @@ -45,7 +45,9 @@ import AVFoundation var endCallkit: Bool = false var globalState : GlobalState = .Off var actionsToPerformOnceWhenCoreIsOn : [(()->Void)] = [] - + + var backgroundContextCall : Call? + @objc var backgroundContextCameraIsEnabled : Bool = false fileprivate override init() { providerDelegate = ProviderDelegate() @@ -113,7 +115,18 @@ import AVFoundation lc?.stopAsync() } } - + + @objc func getBackgroundContextCall() -> OpaquePointer? { + return backgroundContextCall?.getCobject + } + @objc func setBackgroundContextCall(call: OpaquePointer?) { + if (call == nil) { + backgroundContextCall = nil + } else { + backgroundContextCall = Call.getSwiftObject(cObject: call!) + } + } + @objc static func callKitEnabled() -> Bool { #if !targetEnvironment(simulator) if ConfigManager.instance().lpConfigBoolForKey(key: "use_callkit", section: "app") { @@ -150,7 +163,6 @@ import AVFoundation @objc func isBluetoothAvailable() -> Bool { for device in lc!.audioDevices { if (device.type == AudioDeviceType.Bluetooth || device.type == AudioDeviceType.BluetoothA2DP) { - let name = device.deviceName return true; } } @@ -178,6 +190,7 @@ import AVFoundation return false } + func requestTransaction(_ transaction: CXTransaction, action: String) { callController.request(transaction) { error in if let error = error { @@ -237,7 +250,8 @@ import AVFoundation let writablePath = AppManager.recordingFilePathFromCall(address: address?.username ?? "") Log.directLog(BCTBX_LOG_MESSAGE, text: "Record file path: \(String(describing: writablePath))") callParams.recordFile = writablePath - + + try call.acceptWithParams(params: callParams) } catch { Log.directLog(BCTBX_LOG_ERROR, text: "accept call failed \(error)") @@ -468,7 +482,7 @@ import AVFoundation if (cstate == .PushIncomingReceived) { displayIncomingCall(call: call, handle: "Calling", hasVideo: false, callId: callId!, displayName: "Calling") } else { - let video = UIApplication.shared.applicationState == .active && (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false) + let video = (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false) if (call.userData == nil) { let appData = CallAppData() @@ -612,6 +626,7 @@ import AVFoundation } if (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning) { + let check = call.currentParams?.videoEnabled if ((call.currentParams?.videoEnabled ?? false) && CallManager.instance().isReceiverEnabled()) { CallManager.instance().changeRouteToSpeaker() } diff --git a/Classes/CallView.m b/Classes/CallView.m index bf38ef65f..5ace1be38 100644 --- a/Classes/CallView.m +++ b/Classes/CallView.m @@ -563,8 +563,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { return; } - BOOL shouldDisableVideo = - (!currentCall || !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall))); + BOOL shouldDisableVideo = !currentCall || !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)); if (videoHidden != shouldDisableVideo) { if (!shouldDisableVideo) { [self displayVideoCall:animated]; @@ -572,8 +571,9 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [self displayAudioCall:animated]; } } - // camera is diabled duiring conference, it must be activated after leaving conference. - if (!shouldDisableVideo && !linphone_core_is_in_conference(LC)) { + + if (!shouldDisableVideo && !linphone_core_is_in_conference(LC) && // camera is diabled duiring conference, it must be activated after leaving conference. + [UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // Camera should not be enabled when in background) linphone_call_enable_camera(call, TRUE); } [self updateCallView]; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 2fd86fa7a..be99479de 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -98,9 +98,8 @@ return; /* save call context */ - LinphoneManager *instance = LinphoneManager.instance; - instance->currentCallContextBeforeGoingBackground.call = call; - instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call); + [CallManager.instance setBackgroundContextCallWithCall:call]; + [CallManager.instance setBackgroundContextCameraIsEnabled:linphone_call_camera_enabled(call)]; const LinphoneCallParams *params = linphone_call_get_current_params(call); if (linphone_call_params_video_enabled(params)) @@ -126,39 +125,36 @@ [instance.fastAddressBook fetchContactsInBackGroundThread]; instance.fastAddressBook.needToUpdate = FALSE; } + + LinphoneCall *call = linphone_core_get_current_call(LC); - LinphoneCall *call = linphone_core_get_current_call(LC); - - if (call) { - if (call == instance->currentCallContextBeforeGoingBackground.call) { - const LinphoneCallParams *params = - linphone_call_get_current_params(call); - if (linphone_call_params_video_enabled(params)) { - linphone_call_enable_camera( - call, instance->currentCallContextBeforeGoingBackground - .cameraIsEnabled); - } - instance->currentCallContextBeforeGoingBackground.call = 0; - } else if (linphone_call_get_state(call) == - LinphoneCallIncomingReceived) { - if ((floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)) { - if ([LinphoneManager.instance lpConfigBoolForKey:@"autoanswer_notif_preference"]) { - linphone_call_accept(call); - [PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription]; - } else { - [PhoneMainView.instance displayIncomingCall:call]; - } - } else { - // Click the call notification when callkit is disabled, show app view. - [PhoneMainView.instance displayIncomingCall:call]; + if (call) { + if (call == [CallManager.instance getBackgroundContextCall]) { + const LinphoneCallParams *params = + linphone_call_get_current_params(call); + if (linphone_call_params_video_enabled(params)) { + linphone_call_enable_camera(call, [CallManager.instance backgroundContextCameraIsEnabled]); + } + [CallManager.instance setBackgroundContextCallWithCall:nil]; + } else if (linphone_call_get_state(call) == LinphoneCallIncomingReceived) { + if ((floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)) { + if ([LinphoneManager.instance lpConfigBoolForKey:@"autoanswer_notif_preference"]) { + linphone_call_accept(call); + [PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription]; + } else { + [PhoneMainView.instance displayIncomingCall:call]; + } + } else { + // Click the call notification when callkit is disabled, show app view. + [PhoneMainView.instance displayIncomingCall:call]; } - // in this case, the ringing sound comes from the notification. + // in this case, the ringing sound comes from the notification. // To stop it we have to do the iOS7 ring fix... [self fixRing]; - } - } - [LinphoneManager.instance.iapManager check]; + } + } + [LinphoneManager.instance.iapManager check]; if (_shortcutItem) { [self handleShortcut:_shortcutItem]; _shortcutItem = nil; diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 319302535..318d70940 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -74,12 +74,6 @@ typedef enum _NetworkType { extern const int kLinphoneAudioVbrCodecDefaultBitrate; -/* Application specific call context */ -typedef struct _CallContext { - LinphoneCall* call; - bool_t cameraIsEnabled; -} CallContext; - typedef struct _LinphoneManagerSounds { SystemSoundID vibrate; } LinphoneManagerSounds; @@ -99,8 +93,6 @@ typedef struct _LinphoneManagerSounds { UIBackgroundTaskIdentifier pushBgTaskMsg; CTCallCenter* mCallCenter; NSDate *mLastKeepAliveDate; -@public - CallContext currentCallContextBeforeGoingBackground; } + (LinphoneManager*)instance; #ifdef DEBUG diff --git a/Classes/ProviderDelegate.swift b/Classes/ProviderDelegate.swift index f6cbc9e78..a1a69b458 100644 --- a/Classes/ProviderDelegate.swift +++ b/Classes/ProviderDelegate.swift @@ -178,6 +178,12 @@ extension ProviderDelegate: CXProviderDelegate { Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: answer call with call-id: \(String(describing: callId)) and UUID: \(uuid.description).") let call = CallManager.instance().callByCallId(callId: callId) + + if (UIApplication.shared.applicationState != .active) { + CallManager.instance().backgroundContextCall = call + CallManager.instance().backgroundContextCameraIsEnabled = call!.params?.videoEnabled ?? false + call?.cameraEnabled = false // Disable camera while app is not on foreground + } CallManager.instance().lc?.configureAudioSession() CallManager.instance().acceptCall(call: call!, hasVideo: call!.params?.videoEnabled ?? false) action.fulfill()