Default to sofware AEC.

This commit is contained in:
Greyson Parrelli
2022-01-05 15:14:07 -05:00
committed by Alex Hart
parent 0aabf9945f
commit 47134e19f1
8 changed files with 62 additions and 15 deletions

View File

@@ -157,14 +157,13 @@ public final class InternalValues extends SignalStoreValues {
}
/**
* The selected audio processing method to use (for AEC/NS).
* <p>
* The user must be an internal user otherwise the default method will be returned. For
* evaluation, internal users will use software processing by default unless the setting
* is changed in storage.
* Setting to override the default handling of hardware/software AEC.
*/
public synchronized CallManager.AudioProcessingMethod audioProcessingMethod() {
return FeatureFlags.internalUser() ? CallManager.AudioProcessingMethod.values()[getInteger(AUDIO_PROCESSING_METHOD, CallManager.AudioProcessingMethod.ForceSoftware.ordinal())]
: CallManager.AudioProcessingMethod.Default;
if (FeatureFlags.internalUser()) {
return CallManager.AudioProcessingMethod.values()[getInteger(AUDIO_PROCESSING_METHOD, CallManager.AudioProcessingMethod.Default.ordinal())];
} else {
return CallManager.AudioProcessingMethod.Default;
}
}
}

View File

@@ -0,0 +1,33 @@
package org.thoughtcrime.securesms.service.webrtc
import android.os.Build
import org.signal.ringrtc.CallManager.AudioProcessingMethod
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.FeatureFlags
/**
* Utility class to determine which AEC method RingRTC should use.
*/
object AudioProcessingMethodSelector {
private val hardwareModels: Set<String> by lazy {
FeatureFlags.hardwareAecModels()
.split(",")
.map { it.trim() }
.filter { it.isNotEmpty() }
.toSet()
}
@JvmStatic
fun get(): AudioProcessingMethod {
if (SignalStore.internalValues().audioProcessingMethod() != AudioProcessingMethod.Default) {
return SignalStore.internalValues().audioProcessingMethod()
}
return when {
FeatureFlags.forceDefaultAec() -> AudioProcessingMethod.Default
hardwareModels.contains(Build.MODEL) -> AudioProcessingMethod.ForceHardware
else -> AudioProcessingMethod.ForceSoftware
}
}
}

View File

@@ -46,7 +46,7 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
new byte[0],
SignalStore.internalValues().audioProcessingMethod(),
AudioProcessingMethodSelector.get(),
webRtcInteractor.getGroupCallObserver());
return currentState.builder()

View File

@@ -45,7 +45,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
new byte[0],
SignalStore.internalValues().audioProcessingMethod(),
AudioProcessingMethodSelector.get(),
webRtcInteractor.getGroupCallObserver());
try {

View File

@@ -68,7 +68,7 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
SignalStore.internalValues().audioProcessingMethod(),
AudioProcessingMethodSelector.get(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),

View File

@@ -170,7 +170,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
new byte[0],
SignalStore.internalValues().audioProcessingMethod(),
AudioProcessingMethodSelector.get(),
webRtcInteractor.getGroupCallObserver());
try {

View File

@@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
@@ -106,7 +105,7 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
SignalStore.internalValues().audioProcessingMethod(),
AudioProcessingMethodSelector.get(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),

View File

@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.util;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
@@ -89,6 +90,8 @@ public final class FeatureFlags {
private static final String CDSH = "android.cdsh";
private static final String VOICE_NOTE_RECORDING_V2 = "android.voiceNoteRecordingV2.2";
private static final String GROUPS_V2_UPDATE_PAGING = "android.groupsv2.updatePaging";
private static final String HARDWARE_AEC_MODELS = "android.calling.hardwareAecModels";
private static final String FORCE_DEFAULT_AEC = "android.calling.forceDefaultAec";
/**
* We will only store remote values for flags in this set. If you want a flag to be controllable
@@ -131,7 +134,9 @@ public final class FeatureFlags {
DONOR_BADGES_DISPLAY,
CHANGE_NUMBER_ENABLED,
VOICE_NOTE_RECORDING_V2,
GROUPS_V2_UPDATE_PAGING
GROUPS_V2_UPDATE_PAGING,
HARDWARE_AEC_MODELS,
FORCE_DEFAULT_AEC
);
@VisibleForTesting
@@ -187,7 +192,8 @@ public final class FeatureFlags {
DONOR_BADGES_DISPLAY,
DONATE_MEGAPHONE,
VOICE_NOTE_RECORDING_V2,
GROUPS_V2_UPDATE_PAGING
GROUPS_V2_UPDATE_PAGING,
FORCE_DEFAULT_AEC
);
/**
@@ -443,6 +449,16 @@ public final class FeatureFlags {
return getBoolean(GROUPS_V2_UPDATE_PAGING, false);
}
/** A comma-separated list of models that should use hardware AEC for calling. */
public static @NonNull String hardwareAecModels() {
return getString(HARDWARE_AEC_MODELS, "");
}
/** Whether or not all devices should be forced into using default AEC for calling. */
public static boolean forceDefaultAec() {
return getBoolean(FORCE_DEFAULT_AEC, false);
}
/** Only for rendering debug info. */
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
return new TreeMap<>(REMOTE_VALUES);