call: Support voice only incoming call

This commit is contained in:
Valere
2026-03-23 14:55:40 +01:00
committed by Mauro
parent 867d3476c3
commit fec4f7d9ee
16 changed files with 73 additions and 59 deletions
@@ -20,6 +20,7 @@ struct ElementCallConfiguration {
case roomCall(roomProxy: JoinedRoomProxyProtocol,
clientProxy: ClientProxyProtocol,
clientID: String,
voiceOnly: Bool,
elementCallBaseURL: URL,
elementCallBaseURLOverride: URL?,
colorScheme: ColorScheme)
@@ -59,10 +60,12 @@ struct ElementCallConfiguration {
clientID: String,
elementCallBaseURL: URL,
elementCallBaseURLOverride: URL?,
voiceOnly: Bool,
colorScheme: ColorScheme) {
kind = .roomCall(roomProxy: roomProxy,
clientProxy: clientProxy,
clientID: clientID,
voiceOnly: voiceOnly,
elementCallBaseURL: elementCallBaseURL,
elementCallBaseURLOverride: elementCallBaseURLOverride,
colorScheme: colorScheme)
@@ -73,7 +76,7 @@ struct ElementCallConfiguration {
switch kind {
case .genericCallLink(let url):
url.absoluteString
case .roomCall(let roomProxy, _, _, _, _, _):
case .roomCall(let roomProxy, _, _, _, _, _, _):
roomProxy.id
}
}
@@ -25,6 +25,7 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe
let callKitID: UUID
let roomID: String
let rtcNotificationID: String?
let isVoiceCall: Bool
}
private let pushRegistry: PKPushRegistry
@@ -111,7 +112,7 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe
let callID = if let incomingCallID, incomingCallID.roomID == roomID {
incomingCallID
} else {
CallID(callKitID: UUID(), roomID: roomID, rtcNotificationID: nil)
CallID(callKitID: UUID(), roomID: roomID, rtcNotificationID: nil, isVoiceCall: false)
}
incomingCallID = nil
@@ -177,7 +178,9 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe
return
}
let callID = CallID(callKitID: UUID(), roomID: roomID, rtcNotificationID: rtcNotificationID)
let isVoiceCall = payload.dictionaryPayload[ElementCallServiceNotificationKey.isVoiceCall.rawValue] as? Bool ?? false
let callID = CallID(callKitID: UUID(), roomID: roomID, rtcNotificationID: rtcNotificationID, isVoiceCall: isVoiceCall)
incomingCallID = callID
guard let expirationDate = (payload.dictionaryPayload[ElementCallServiceNotificationKey.expirationDate.rawValue] as? Date) else {
@@ -199,7 +202,7 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe
let roomDisplayName = payload.dictionaryPayload[ElementCallServiceNotificationKey.roomDisplayName.rawValue] as? String
let update = CXCallUpdate()
update.hasVideo = true
update.hasVideo = !isVoiceCall
update.localizedCallerName = roomDisplayName
// https://stackoverflow.com/a/41230020/730924
update.remoteHandle = .init(type: .generic, value: roomID)
@@ -271,7 +274,7 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe
// Then end the and call rely on `setupCallSession` to create a new one
provider.reportCall(with: incomingCallID.callKitID, endedAt: nil, reason: .remoteEnded)
self.actionsSubject.send(.startCall(roomID: incomingCallID.roomID))
self.actionsSubject.send(.startCall(roomID: incomingCallID.roomID, isVoiceCall: incomingCallID.isVoiceCall))
self.endUnansweredCallTask?.cancel()
}
}
@@ -16,6 +16,7 @@ enum ElementCallServiceNotificationKey: String {
case rtcNotifyEventID
/// The Date at which the incoming call should stop ringing.
case expirationDate
case isVoiceCall
}
let ElementCallServiceNotificationDiscardDelta = 15.0
@@ -10,7 +10,7 @@ import Combine
enum ElementCallServiceAction {
case receivedIncomingCallRequest
case startCall(roomID: String)
case startCall(roomID: String, isVoiceCall: Bool)
case endCall(roomID: String)
case setAudioEnabled(_ enabled: Bool, roomID: String)
}
@@ -70,6 +70,7 @@ final class ElementCallWidgetDriver: WidgetCapabilitiesProvider, ElementCallWidg
func start(baseURL: URL,
clientID: String,
colorScheme: ColorScheme,
voiceOnly: Bool,
rageshakeURL: String?,
analyticsConfiguration: ElementCallAnalyticsConfiguration?) async -> Result<URL, ElementCallWidgetDriverError> {
guard let room = room as? Room else {
@@ -77,7 +78,7 @@ final class ElementCallWidgetDriver: WidgetCapabilitiesProvider, ElementCallWidg
}
async let useEncryption = (try? room.latestEncryptionState() == .encrypted) ?? false
async let intent = room.joinCallIntent
async let intent = room.joinCallIntent(voiceOnly: voiceOnly)
let widgetSettings: WidgetSettings
do {
@@ -92,6 +93,7 @@ final class ElementCallWidgetDriver: WidgetCapabilitiesProvider, ElementCallWidg
posthogApiKey: analyticsConfiguration?.posthogAPIKey,
rageshakeSubmitUrl: rageshakeURL,
sentryDsn: analyticsConfiguration?.sentryDSN,
sentryEnvironment: nil),
config: .init(intent: intent))
} catch {
@@ -33,6 +33,7 @@ protocol ElementCallWidgetDriverProtocol {
func start(baseURL: URL,
clientID: String,
colorScheme: ColorScheme,
voiceOnly: Bool,
rageshakeURL: String?,
analyticsConfiguration: ElementCallAnalyticsConfiguration?) async -> Result<URL, ElementCallWidgetDriverError>
@@ -27,6 +27,7 @@ class GenericCallLinkWidgetDriver: ElementCallWidgetDriverProtocol {
func start(baseURL: URL,
clientID: String,
colorScheme: ColorScheme,
voiceOnly: Bool,
rageshakeURL: String?,
analyticsConfiguration: ElementCallAnalyticsConfiguration?) async -> Result<URL, ElementCallWidgetDriverError> {
MXLog.error("Nothing to start, use the configuration's URL directly instead.")