diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index 9478e974e0..3b63d46119 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -8,6 +8,7 @@ import android.widget.Toast import androidx.lifecycle.ViewModelProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.signal.core.util.concurrent.SignalExecutors +import org.signal.ringrtc.CallManager import org.thoughtcrime.securesms.BuildConfig import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.settings.DSLConfiguration @@ -321,6 +322,19 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter ) } + sectionHeaderPref(R.string.preferences__internal_audio) + + radioListPref( + title = DSLSettingsText.from(R.string.preferences__internal_audio_processing_method), + listItems = CallManager.AudioProcessingMethod.values().map { it.name }.toTypedArray(), + selected = CallManager.AudioProcessingMethod.values().indexOf(state.audioProcessingMethod), + onSelected = { + viewModel.setInternalAudioProcessingMethod(CallManager.AudioProcessingMethod.values()[it]) + } + ) + + dividerPref() + if (FeatureFlags.donorBadges() && SignalStore.donationsValues().getSubscriber() != null) { sectionHeaderPref(R.string.preferences__internal_badges) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt index e17e9f5a77..cb75a837d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.components.settings.app.internal +import org.signal.ringrtc.CallManager import org.thoughtcrime.securesms.emoji.EmojiFiles data class InternalSettingsState( @@ -13,6 +14,7 @@ data class InternalSettingsState( val disableAutoMigrationNotification: Boolean, val forceCensorship: Boolean, val callingServer: String, + val audioProcessingMethod: CallManager.AudioProcessingMethod, val useBuiltInEmojiSet: Boolean, val emojiVersion: EmojiFiles.Version?, val removeSenderKeyMinimium: Boolean, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt index b026d8a1d1..8145afde6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.components.settings.app.internal import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import org.signal.ringrtc.CallManager import org.thoughtcrime.securesms.keyvalue.InternalValues import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.livedata.Store @@ -90,6 +91,11 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito refresh() } + fun setInternalAudioProcessingMethod(method: CallManager.AudioProcessingMethod) { + preferenceDataStore.putInt(InternalValues.AUDIO_PROCESSING_METHOD, method.ordinal) + refresh() + } + private fun refresh() { store.update { getState().copy(emojiVersion = it.emojiVersion) } } @@ -105,6 +111,7 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito disableAutoMigrationNotification = SignalStore.internalValues().disableGv1AutoMigrateNotification(), forceCensorship = SignalStore.internalValues().forcedCensorship(), callingServer = SignalStore.internalValues().groupCallingServer(), + audioProcessingMethod = SignalStore.internalValues().audioProcessingMethod(), useBuiltInEmojiSet = SignalStore.internalValues().forceBuiltInEmoji(), emojiVersion = null, removeSenderKeyMinimium = SignalStore.internalValues().removeSenderKeyMinimum(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java index 0f7aa0cfde..f2a6ae91fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.keyvalue; import androidx.annotation.NonNull; +import org.signal.ringrtc.CallManager; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.util.FeatureFlags; @@ -23,6 +24,7 @@ public final class InternalValues extends SignalStoreValues { public static final String REMOVE_SENDER_KEY_MINIMUM = "internal.remove_sender_key_minimum"; public static final String DELAY_RESENDS = "internal.delay_resends"; public static final String CALLING_SERVER = "internal.calling_server"; + public static final String AUDIO_PROCESSING_METHOD = "internal.audio_processing_method"; public static final String SHAKE_TO_REPORT = "internal.shake_to_report"; public static final String DISABLE_STORAGE_SERVICE = "internal.disable_storage_service"; @@ -153,4 +155,16 @@ public final class InternalValues extends SignalStoreValues { } return internalServer != null ? internalServer : BuildConfig.SIGNAL_SFU_URL; } + + /** + * The selected audio processing method to use (for AEC/NS). + *
+ * 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.
+ */
+ public synchronized CallManager.AudioProcessingMethod audioProcessingMethod() {
+ return FeatureFlags.internalUser() ? CallManager.AudioProcessingMethod.values()[getInteger(AUDIO_PROCESSING_METHOD, CallManager.AudioProcessingMethod.ForceSoftware.ordinal())]
+ : CallManager.AudioProcessingMethod.Default;
+ }
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupNetworkUnavailableActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupNetworkUnavailableActionProcessor.java
index 92c1182219..5405105e76 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupNetworkUnavailableActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupNetworkUnavailableActionProcessor.java
@@ -45,7 +45,7 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
- currentState.getVideoState().getLockableEglBase().require(),
+ SignalStore.internalValues().audioProcessingMethod(),
webRtcInteractor.getGroupCallObserver());
return currentState.builder()
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java
index d62899fa51..bc9606d03e 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java
@@ -44,7 +44,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
- currentState.getVideoState().getLockableEglBase().require(),
+ SignalStore.internalValues().audioProcessingMethod(),
webRtcInteractor.getGroupCallObserver());
try {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java
index fd9b580e5d..a1db47e3c2 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java
@@ -68,6 +68,7 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
+ SignalStore.internalValues().audioProcessingMethod(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java
index f3a62bda7e..4b9ad1a2d0 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java
@@ -169,7 +169,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
SignalStore.internalValues().groupCallingServer(),
- currentState.getVideoState().getLockableEglBase().require(),
+ SignalStore.internalValues().audioProcessingMethod(),
webRtcInteractor.getGroupCallObserver());
try {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java
index 91db1ff943..fd5cad52cd 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java
@@ -14,6 +14,7 @@ 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;
@@ -105,6 +106,7 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.getCallManager().proceed(activePeer.getCallId(),
context,
videoState.getLockableEglBase().require(),
+ SignalStore.internalValues().audioProcessingMethod(),
videoState.requireLocalSink(),
callParticipant.getVideoSink(),
videoState.requireCamera(),
@@ -149,7 +151,7 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
byte[] remoteIdentityKey = WebRtcUtil.getPublicKeyBytes(receivedAnswerMetadata.getRemoteIdentityKey());
byte[] localIdentityKey = WebRtcUtil.getPublicKeyBytes(IdentityKeyUtil.getIdentityKey(context).serialize());
- webRtcInteractor.getCallManager().receivedAnswer(callMetadata.getCallId(), callMetadata.getRemoteDevice(), answerMetadata.getOpaque(), receivedAnswerMetadata.isMultiRing(), remoteIdentityKey, localIdentityKey);
+ webRtcInteractor.getCallManager().receivedAnswer(callMetadata.getCallId(), callMetadata.getRemoteDevice(), answerMetadata.getOpaque(), remoteIdentityKey, localIdentityKey);
} catch (CallException | InvalidKeyException e) {
return callFailure(currentState, "receivedAnswer() failed: ", e);
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java
index cbb46c1ea8..d581c4e282 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java
@@ -472,7 +472,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
return p.handleReceivedOfferWhileActive(s, remotePeer);
case ENDED_LOCAL_HANGUP:
case ENDED_APP_DROPPED_CALL:
- case IGNORE_CALLS_FROM_NON_MULTIRING_CALLERS:
Log.i(TAG, "Ignoring event: " + event);
break;
default:
@@ -562,17 +561,17 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
}
@Override
- public void onSendHangup(@NonNull CallId callId, @Nullable Remote remote, @NonNull Integer remoteDevice, @NonNull Boolean broadcast, @NonNull CallManager.HangupType hangupType, @NonNull Integer deviceId, @NonNull Boolean useLegacyHangupMessage) {
+ public void onSendHangup(@NonNull CallId callId, @Nullable Remote remote, @NonNull Integer remoteDevice, @NonNull Boolean broadcast, @NonNull CallManager.HangupType hangupType, @NonNull Integer deviceId) {
if (!(remote instanceof RemotePeer)) {
return;
}
RemotePeer remotePeer = (RemotePeer) remote;
- Log.i(TAG, "onSendHangup: id: " + remotePeer.getCallId().format(remoteDevice) + " type: " + hangupType.name() + " isLegacy: " + useLegacyHangupMessage);
+ Log.i(TAG, "onSendHangup: id: " + remotePeer.getCallId().format(remoteDevice) + " type: " + hangupType.name());
WebRtcData.CallMetadata callMetadata = new WebRtcData.CallMetadata(remotePeer, remoteDevice);
- WebRtcData.HangupMetadata hangupMetadata = new WebRtcData.HangupMetadata(WebRtcUtil.getHangupTypeFromCallHangupType(hangupType), useLegacyHangupMessage, deviceId);
+ WebRtcData.HangupMetadata hangupMetadata = new WebRtcData.HangupMetadata(WebRtcUtil.getHangupTypeFromCallHangupType(hangupType), false, deviceId);
process((s, p) -> p.handleSendHangup(s, callMetadata, hangupMetadata, broadcast));
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java
index 0084c2cf73..eae255f0e7 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java
@@ -213,7 +213,6 @@ public abstract class WebRtcActionProcessor {
messageAgeSec,
WebRtcUtil.getCallMediaTypeFromOfferType(offerMetadata.getOfferType()),
1,
- receivedOfferMetadata.isMultiRing(),
true,
remoteIdentityKey,
localIdentityKey);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c63632a4aa..c0df406c37 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2594,6 +2594,8 @@