Add new remote config support for calling audio configuration.

This commit is contained in:
Jim Gustafson
2025-04-29 11:37:32 -07:00
committed by Cody Henthorne
parent 2421bbdabb
commit 570a475229
16 changed files with 777 additions and 150 deletions

View File

@@ -66,8 +66,7 @@ class CallLinkPreJoinActionProcessor(
callLink.credentials.adminPassBytes,
ByteArray(0),
AUDIO_LEVELS_INTERVAL,
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
webRtcInteractor.groupCallObserver
)
} catch (e: InvalidInputException) {

View File

@@ -52,8 +52,7 @@ public class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcesso
SignalStore.internal().getGroupCallingServer(),
new byte[0],
null,
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
webRtcInteractor.getGroupCallObserver());
if (groupCall == null) {

View File

@@ -50,8 +50,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
SignalStore.internal().getGroupCallingServer(),
new byte[0],
AUDIO_LEVELS_INTERVAL,
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
webRtcInteractor.getGroupCallObserver());
if (groupCall == null) {

View File

@@ -103,8 +103,7 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),

View File

@@ -186,8 +186,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
SignalStore.internal().getGroupCallingServer(),
new byte[0],
AUDIO_LEVELS_INTERVAL,
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
webRtcInteractor.getGroupCallObserver());
if (groupCall == null) {

View File

@@ -152,8 +152,7 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
RingRtcDynamicConfiguration.shouldUseOboeAdm(),
RingRtcDynamicConfiguration.getAudioConfig(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),

View File

@@ -2,73 +2,42 @@ package org.thoughtcrime.securesms.service.webrtc
import android.os.Build
import org.signal.core.util.asListContains
import org.signal.ringrtc.CallManager.AudioProcessingMethod
import org.signal.ringrtc.AudioConfig
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.RemoteConfig
import org.thoughtcrime.securesms.webrtc.audio.AudioDeviceConfig
/**
* Utility class to determine which AEC method RingRTC should use.
* Utility class to determine the audio configuration that RingRTC should use.
*/
object RingRtcDynamicConfiguration {
private val KNOWN_ISSUE_ROMS = "(lineage|calyxos)".toRegex(RegexOption.IGNORE_CASE)
@JvmStatic
fun getAudioProcessingMethod(): AudioProcessingMethod {
if (SignalStore.internal.callingAudioProcessingMethod != AudioProcessingMethod.Default) {
return SignalStore.internal.callingAudioProcessingMethod
}
return if (shouldUseOboeAdm()) {
when {
shouldUseSoftwareAecForOboe() || isKnownFaultyHardwareImplementation() -> AudioProcessingMethod.ForceSoftwareAec3
else -> AudioProcessingMethod.ForceHardware
}
} else {
when {
isHardwareBlocklisted() || isKnownFaultyHardwareImplementation() -> AudioProcessingMethod.ForceSoftwareAec3
isSoftwareBlocklisted() -> AudioProcessingMethod.ForceHardware
Build.VERSION.SDK_INT < 29 && RemoteConfig.useHardwareAecIfOlderThanApi29 -> AudioProcessingMethod.ForceHardware
Build.VERSION.SDK_INT < 29 -> AudioProcessingMethod.ForceSoftwareAec3
else -> AudioProcessingMethod.ForceHardware
}
}
}
private var lastFetchTime: Long = 0
fun isTelecomAllowedForDevice(): Boolean {
return RemoteConfig.telecomManufacturerAllowList.lowercase().asListContains(Build.MANUFACTURER.lowercase()) &&
!RemoteConfig.telecomModelBlocklist.lowercase().asListContains(Build.MODEL.lowercase())
}
private fun isHardwareBlocklisted(): Boolean {
return RemoteConfig.hardwareAecBlocklistModels.asListContains(Build.MODEL)
}
private fun isKnownFaultyHardwareImplementation(): Boolean {
return Build.PRODUCT.contains(KNOWN_ISSUE_ROMS) ||
Build.DISPLAY.contains(KNOWN_ISSUE_ROMS) ||
Build.HOST.contains(KNOWN_ISSUE_ROMS)
}
private fun isSoftwareBlocklisted(): Boolean {
return RemoteConfig.softwareAecBlocklistModels.asListContains(Build.MODEL)
}
@JvmStatic
fun shouldUseOboeAdm(): Boolean {
if (RemoteConfig.internalUser) {
return SignalStore.internal.callingEnableOboeAdm
fun getAudioConfig(): AudioConfig {
if (RemoteConfig.internalUser && SignalStore.internal.callingSetAudioConfig) {
// Use the internal audio settings.
var audioConfig = AudioConfig()
audioConfig.useOboe = SignalStore.internal.callingUseOboeAdm
audioConfig.useSoftwareAec = SignalStore.internal.callingUseSoftwareAec
audioConfig.useSoftwareNs = SignalStore.internal.callingUseSoftwareNs
audioConfig.useInputLowLatency = SignalStore.internal.callingUseInputLowLatency
audioConfig.useInputVoiceComm = SignalStore.internal.callingUseInputVoiceComm
return audioConfig
}
// For now, only allow the Oboe ADM to be used for custom ROMS.
return RemoteConfig.oboeDeployment && isKnownFaultyHardwareImplementation() && !shouldUseJavaAdm()
}
private fun shouldUseJavaAdm(): Boolean {
return RemoteConfig.useJavaAdmModels.asListContains(Build.MODEL)
}
private fun shouldUseSoftwareAecForOboe(): Boolean {
return RemoteConfig.useSoftwareAecForOboeModels.asListContains(Build.MODEL)
// Use the audio settings provided by the remote configuration.
if (lastFetchTime != SignalStore.remoteConfig.lastFetchTime) {
// The remote config has been updated.
AudioDeviceConfig.refresh()
lastFetchTime = SignalStore.remoteConfig.lastFetchTime
}
return AudioDeviceConfig.getCurrentConfig()
}
}